home *** CD-ROM | disk | FTP | other *** search
/ Power CD / Power CD ATARI-Rechner Lieben.iso / UTILITY / LSRC_222 / LHARC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-29  |  80.4 KB  |  4,699 lines

  1.  
  2. #include "lharc.h"
  3.  
  4. #define VERSION    "2.22"
  5. #define __030    0
  6. #define BETA    0
  7. #define GERMAN    1
  8.  
  9. #ifdef __SHELL__
  10. #undef GERMAN
  11. #undef BETA
  12. #define GERMAN    0
  13. #define    BETA    0
  14. #endif
  15.  
  16. #if GERMAN
  17.     #include "usageger.h"
  18. #else
  19.     #include "usageeng.h"
  20. #endif
  21.  
  22. uchar *errmes[]={
  23. M_UNKNOWNERR,M_INVCMDERR,M_MANYPATERR,M_NOARCNMERR,M_NOFNERR,M_NOARCERR,M_RENAMEERR,M_MKTMPERR,
  24. M_DUPFNERR,M_TOOMANYERR,M_TOOLONGERR,M_NOFILEERR,M_MKFILEERR,M_RDERR,M_WTERR,M_MEMOVRERR,M_INVSWERR,
  25. M_CTRLBRK,M_NOMATCHERR,M_COPYERR,M_NOTLZH,M_OVERWT,M_MKDIR,M_MKDIRERR,M_CRCERR,M_RDONLY};
  26.  
  27. ushort    left[2*NC-1],right[2*NC-1];
  28. uchar    c_len[NC],pt_len[NPT],*len;
  29. ushort    c_freq[2*NC-1],c_code[NC],p_freq[2*NP-1],pt_table[256],pt_code[NPT],t_freq[2*NT-1];
  30. ushort    *freq,len_cnt[17];
  31. int        heap[NC+1];
  32.  
  33. _DTA    _dta;
  34. XATTR    xattr;
  35. FILE    *file1,*file2,*file3,*StdOut=stdout;
  36. int     args,c_err,skipped,cmd,cmdupdate,cmdlist,errorlevel,oldtos;
  37. int        _gemdos,Nfile,fbfiles,cpu;
  38. long    arcpos0,arcpos1,lastarcpos,lastarclen,nextarcpos,arclen,maxlen,old_afx;
  39. long    act_len,file_len,bsize,o_handle=-1,i_handle=-1,o_dev=-1,i_dev=-1;
  40. uchar    act_dir[MAXPATH],basedir[MAXPATH],workdir[MAXPATH],incldir[MAXPATH];
  41. uchar    *unpack="*.ZOO,*.ZIP,*.AR[CJ],*.LZ[HS],*.LHA,*.TAZ";
  42. uchar    *infname,*outfname,*fbuf,*fbnxt,*o_dir;
  43. ulong    fblft,fbmax;
  44. filebuf    *fblast;
  45.  
  46. uchar    SystemId,has_crc,back_1,back_2;
  47. int     patno,exno,maxblk=64,UnixArc,UnixFile,regcnt,wild_arc,multi_arc,all;
  48. int        fn_name=12,pt_name=128,Case=_PC_CASECONV,min_len,garbage,Device;
  49.  
  50. int     n,heapsize,hdr_len,header_len,ignfile;
  51. uchar    *buf=text_buf,*pager,*com_name,*buffer_start,*buffer_last,pack;
  52. uchar    flg_r,flg_p,flg_x,flg_m,flg_a,flg_c,flg_v,flg_w,flg_z,flg_g,flg_L=2,flg_N,flg_B,flg_W,flg_5;
  53. uchar    flg_d,flg_u,flg_s,flg_e,flg_unpacked,ex_len,flg_j,flg_chk,flg_S,flg_R,flg_I,flg_U=1,flg_K;
  54. uchar    flg_t,flg_arc,flg_h,flg_i,flg_backup,flg_f,flg_4,flg_q,flg_A,flg_X,pnt='.',buffered;
  55. uchar    method=5,FlgMethod=5,copying,obj,ptitel,pargs;
  56. char    flg_k=-1;
  57.  
  58. uchar    swi[]="UwCrpxmacntvhifzedgjqsLSRBAWXKybluok54PMNI";
  59. uchar    *swipos[]={&flg_U,&flg_w,&flg_chk,&flg_r,&flg_p,&flg_x,&flg_m,&flg_a,&flg_c,&flg_n,&flg_t,&flg_v,&flg_h,&flg_i,
  60.         &flg_f,&flg_z,&flg_e,&flg_d,&flg_g,&flg_j,&flg_q,&flg_s,&flg_L,&flg_S,&flg_R,&flg_B,&flg_A,&flg_W,&flg_X,&flg_K};
  61.  
  62. #define    SWI_CNT    30
  63.  
  64. LzHead    Hdr1,Hdr2;
  65. _DOSTIME arcstamp,newer;
  66.  
  67. uchar    arcname[MAXPATH],pathname[MAXPATH],backup1[MAXPATH],backup2[MAXPATH];
  68. uchar    filename[MAXPATH],dosfilename[MAXPATH],matchfilename[MAXPATH],comment[MAXCOMMENT+256];
  69. uchar    buffer[(BUFFERSIZ+128+32)<<2],*buffer_1,*buffer_2,*buffer_3,*buffer_gen;
  70. uchar    travel_wild[MAX_PAT],*exclude_file[MAX_EXCLD],fileregbuf[FILEBUFSIZ],*fileptr;
  71. uchar    *travel_path[MAX_PAT],travel_rel[MAX_PAT];
  72. int     patcnt[MAX_PAT],travel_len[MAX_PAT],travel_file[MAX_PAT],arc_file[MAX_ARC];
  73.  
  74. #if BETA
  75. long timer;
  76. #define INIT_TIMER    timer=clock()
  77. #define EXIT_TIMER    timer=clock() - timer; if (!flg_q) printf(" Time : %ld ms \n",(timer*5))
  78. #else
  79. #define INIT_TIMER
  80. #define EXIT_TIMER
  81. #endif
  82.  
  83. clock_t now;
  84.  
  85. void getnow(void)
  86. {
  87.     now=*((unsigned long *) 0x4baL);
  88. }clock_t clock(void){    (void) Supexec(getnow);    return (now);}
  89.  
  90. #define  A          16807L
  91. #define  M   2147483647L
  92. #define  Q       127773L
  93. #define  R         2836L
  94. long _lseed;int temp(void){    _lseed=A * ((_lseed % Q) + R) - R * (_lseed / Q);    if (_lseed<0)        _lseed+=M;    return((int) _lseed & 4095);}
  95. #define multi_wild(f)    (strchr((f),',')!=NULL)
  96.  
  97. int wildcard(uchar *file)
  98. {
  99.     if (!flg_W && strpbrk(file,"*?[]@|^"))
  100.         return(SUCCS);
  101.     else
  102.         return(FAULT);
  103. }
  104.  
  105. void InitTree(void)
  106. {
  107.     register int i,nil_2=NIL<<1,*p;
  108.  
  109.     p=dad;
  110.     for (i=N;--i>=0;)
  111.         *p++=nil_2;
  112.  
  113.     p=&rson[N+1];
  114.     for (i=256;--i>=0;)
  115.         *p++=nil_2;
  116. }
  117.  
  118. int LSeek(FILE *fp, long offset, int origin){    register long pos,realpos,count;    register unsigned int f;
  119.     register int rv;    f=(fp->_flag&=~_IOEOF);    count=fp->_cnt;        if ((f & _IOWRT) || (count==0) || (origin==SEEK_END))
  120.     {        rv=fflush(fp);        return(((rv==EOF) || (Fseek(offset,fp->_file,origin)<0)) ? -1 : 0);    }    if ((realpos=Fseek(0l,fp->_file,SEEK_CUR))<0)        return(-1);    pos=offset + count - realpos;    if ((!(f & _IORW)) && (pos<=count) && (pos>=(fp->_base-fp->_ptr)))
  121.     {
  122.         fp->_ptr+=pos;        fp->_cnt-=pos;        return(0);    }
  123.     else
  124.     {
  125.         fp->_ptr=fp->_base;        fp->_cnt=0;        if (f & _IORW)
  126.             fp->_flag=(f & (~_IOREAD));
  127.         return((Fseek(offset,fp->_file,origin)<0) ? -1 : 0);
  128.     }}
  129. int sseek(FILE *file,long pos,int end)
  130. {
  131.     if (pos>=arclen || LSeek(file,pos,SEEK_SET))
  132.     {
  133.         if (end)
  134.             LSeek(file,0l,SEEK_END);
  135.         return(-1);
  136.     }
  137.     else
  138.         return(0);
  139. }
  140.  
  141. void message(uchar *p,uchar *q)
  142. {
  143.     if (!flg_q)
  144.         printf("%s: %s\n",p,q);
  145. }
  146.  
  147. #if __030
  148. void get_cpu(long cookie, long *value)
  149. {
  150.     register long old_stack,*cookiejar;
  151.  
  152.     cpu=0;
  153.  
  154.     old_stack = Super (NULL);
  155.     cookiejar = *((long **) 0x5a0l);
  156.     Super ((void *) old_stack);
  157.  
  158.     if (cookiejar)
  159.     {
  160.         while (*cookiejar)
  161.         {
  162.             if (*cookiejar==(long) '_CPU')
  163.             {
  164.                 cpu=(int) (*++cookiejar);
  165.                 return;
  166.             }
  167.             cookiejar += 2;
  168.         }
  169.     }
  170. }
  171. #endif
  172.  
  173. int slash(uchar *path,int set)
  174. {
  175.     register int len;
  176.  
  177.     if (path)
  178.         if ((len=(int) strlen(path) - 1)>=0)
  179.         {
  180.             path+=len;
  181.  
  182.             if (*path++!='\\')
  183.             {
  184.                 if (set>0)
  185.                 {
  186.                     *path++='\\';
  187.                     *path++='\0';
  188.                 }
  189.                 else
  190.                     return(SUCCS);
  191.             }
  192.             else if (!set)
  193.                 *--path='\0';
  194.         }
  195.  
  196.     return(FAULT);
  197. }
  198.  
  199. uchar _proc_str[]="\r         : %3d%% (%Nld/%Nld)";
  200. uchar _frozen_str[]="\r         : %Nld -> %Nld (%3d%%) \n";
  201.  
  202. void proc_ind(void)
  203. {
  204.     if ((act_len+=blocksize)>=file_len || blkcnt<=0)
  205.         printf(_proc_str,100,file_len,file_len);
  206.     else
  207.         printf(_proc_str,(int) ((act_len*100l)/file_len),act_len,file_len);
  208.     fflush(stdout);
  209. }
  210.  
  211. int arc_ext(uchar *x)
  212. {
  213.     x++;
  214.  
  215.     if (stricmp("LZH",x) && stricmp("LHA",x) && stricmp("LZS",x))
  216.         return(FAULT);
  217.     else
  218.         return(SUCCS);
  219. }
  220.  
  221. int path_conf(uchar *path,int mode)
  222. {
  223.     if (get_fname(path)>path)
  224.         return((int) pathconf(path,mode));
  225.     else
  226.         return((int) pathconf(act_dir,mode));
  227. }
  228.  
  229. int case_sensitive(uchar *path)
  230. {
  231.     if (path_conf(path,-1)<_PC_CASE)
  232.         return(_PC_CASECONV);
  233.     else
  234.         return((int) path_conf(path,_PC_CASE));
  235. }
  236.  
  237. #ifndef __SHELL__
  238. void wait_for_key(int newline)
  239. {
  240.     if (flg_h && i_handle<0 && o_handle<0)
  241.     {
  242.         printf(M_PRESSKEY);
  243.         fflush(stdout);
  244.  
  245.         fflush(stdin);
  246.         getch();
  247.  
  248.         if (newline)
  249.             new_line();
  250.     }
  251. }
  252. #endif
  253.  
  254. void lha_exit(void)
  255. {
  256. #ifndef __SHELL__
  257.     if (i_handle>=0)
  258.     {
  259.         if (i_dev>=0)
  260.             Fforce(0,(int) i_dev);
  261.         Fclose((int) i_handle);
  262.     }
  263.  
  264.     if (o_handle>=0)
  265.     {
  266.         if (o_dev>=0)
  267.             Fforce(1,(int) o_dev);
  268.         Fclose((int) o_handle);
  269.     }
  270.  
  271.     if (flg_K)
  272.     {
  273.         register long time=clock()+(CLK_TCK>>2);
  274.  
  275.         for (flg_K<<=2;flg_K>0;flg_K--)
  276.         {
  277.             while (clock()<time);
  278.             time+=(CLK_TCK>>2);
  279.             Cconout(7);
  280.         }
  281.     }
  282.  
  283.     wait_for_key(1);
  284.     exit(errorlevel);
  285. #endif
  286. }
  287.  
  288. #define close(f)    if (f!=NULL) fclose(f);f=NULL
  289.  
  290. void error(int errcode,uchar *p,int err)
  291. {
  292.     if (err && old_afx)
  293.         afxonoff(old_afx);
  294.  
  295.     if (copying)
  296.     {
  297.         if (!flg_q)
  298.             printf("\n%s\n",M_COPYERR);
  299.         close(file1);
  300.         unlink(arcname);
  301.     }
  302.  
  303.     if (!flg_q)
  304.     {
  305.         new_line();
  306.  
  307.         if (p)
  308.             printf("%s: %s\n",errmes[errcode],p);
  309.         else
  310.             puts(errmes[errcode]);
  311.     }
  312.  
  313.     if (file3 && (err || cmd!='P'))
  314.     {
  315.         close(file3);
  316.         if (!cmdupdate && cmd!='C')
  317.             unlink(pathname);
  318.     }
  319.  
  320.     if (err)
  321.     {
  322.         if (file1)
  323.         {
  324.             close(file1);
  325.             if (!Device && back_1)
  326.                 rename(backup1,arcname);
  327.         }
  328.  
  329.         if (file2)
  330.         {
  331.             close(file2);
  332.             if (!Device && (back_2 || cmd=='C'))
  333.             {
  334.                 if (copying)
  335.                 {
  336.                     register uchar path[MAXPATH];
  337.                     strcpy(backpath(strcpy(path,backup2)),get_fname(arcname));
  338.                     rename(backup2,path);
  339.                 }
  340.                 else
  341.                     unlink(backup2);
  342.             }
  343.         }
  344.     }
  345.  
  346.     switch (errcode)
  347.     {
  348.         case MEMOVRERR:
  349.             errorlevel|=512;
  350.             break;
  351.         case RDERR:
  352.         case RDONLY:
  353.             errorlevel|=8;
  354.             break;
  355.         case WTERR:
  356.             errorlevel|=4;
  357.             break;
  358.         case RENAMEERR:
  359.         case MKDIRERR:
  360.             errorlevel|=16;
  361.             break;
  362.         case MKFILEERR:
  363.         case MKTMPERR:
  364.             errorlevel|=32;
  365.             break;
  366.         case NOFILEERR:
  367.         case NOFNERR:
  368.             errorlevel|=256;
  369.             break;
  370.         case NOARCERR:
  371.         case NOARCNMERR:
  372.             errorlevel|=128;
  373.     }
  374.  
  375.     if (copying)
  376.         errorlevel|=32;
  377.  
  378.     if (err==SUCCS)
  379.         lha_exit();
  380. }
  381.  
  382. FILE *e_fopen(uchar *fname,uchar *buffer,uchar *mode,int errID,int err)
  383. {
  384.     register FILE *f;
  385.  
  386.     if ((f=fopen(fname,mode))==NULL)
  387.     {
  388.         if (errno==EACCES)
  389.             error(RDONLY,fname,err);
  390.         else
  391.             error(errID,fname,err);
  392.     }
  393.     else if (buffer)
  394.         setvbuf(f,buffer,_IOFBF,bsize);
  395.  
  396.     return(f);
  397. }
  398.  
  399. uint get_key(uchar *keys)
  400. {
  401.     register uchar key;
  402.  
  403.     fflush(stdout);
  404.     do
  405.     {
  406.         key=(uchar) toupper((int) getch());
  407. #if GERMAN
  408.         if (key=='J')
  409.             key='Y';
  410. #endif
  411.     } while (!strchr(keys,key));
  412.  
  413.     printf("%c\n",key);
  414.     return(key);
  415. }
  416.  
  417. void ShipOut(void)
  418. {
  419.     ship++;
  420.     shipout();
  421.     ship=0;
  422. }
  423.  
  424. void tstpat(void)
  425. {
  426.     register int i;
  427.  
  428.     if (!Nfile)
  429.     {
  430.         if (!flg_q)
  431.             puts(M_NOFILEERR);
  432.         errorlevel|=256;
  433.         return;
  434.     }
  435.  
  436.     for (i=patno;--i>=0;)
  437.         if (!patcnt[i] && !travel_wild[i])
  438.         {
  439.             if (!flg_q)
  440.                 printf("%s: %s\n",M_NOMATCHERR,&fileregbuf[travel_file[i]]);
  441.             errorlevel|=256;
  442.         }
  443. }
  444.  
  445. void sethdr(uchar *fn,uint attr,_DOSTIME *time,LzHead *h,int name)
  446. {
  447.     register uchar *id;
  448.     register uint l;
  449.  
  450.     memset(h,0,sizeof(LzHead));
  451.  
  452.     l=(uint) strlen(fn);
  453.     if (name==SUCCS && flg_x==2 && *fn!='\\')
  454.     {
  455.         h->Fname[1]='\\';
  456.         memcpy(h->Fname+2,fn,l++);
  457.     }
  458.     else
  459.         memcpy(h->Fname+1,fn,l);
  460.  
  461.     if ((attr & FA_DIR) && (h->Fname[l]!='\\'))
  462.         h->Fname[++l]='\\';
  463.  
  464.     h->Fname[0]=l;
  465.     h->Attr=attr;
  466.     h->Level=flg_k>0 ? flg_k : 0;
  467.     h->Ftime=*time;
  468.     h->HeadSiz=l+22+ex_len;
  469.  
  470.     if (file3)
  471.     {
  472.         h->OrgSiz=textsize=Fseek(0l,file3->_file,SEEK_END);
  473.         Fseek(0l,file3->_file,SEEK_SET);
  474.     }
  475.     else
  476.         h->OrgSiz=textsize=0;
  477.  
  478.     method=FlgMethod;
  479.     codesize=compsize=0;
  480.  
  481.     if (attr & FA_DIR)
  482.         id="-lhd-";
  483.     else if (cmd=='C')
  484.         id="-afx-";
  485.     else if (!method)
  486.         id="-lz5-";
  487.     else if (method==1)
  488.         id="-lh1-";
  489.     else if (method==5)
  490.         id="-lh5-";
  491.     else
  492.         id="-lz4-";
  493.  
  494.     memcpy(h->HeadID,id,5);
  495. }
  496.  
  497. uint make_ext(uchar *dest,uchar *source,uchar id,int last)
  498. {
  499.     register uint len;
  500.  
  501.     if ((len=(uint) strlen(source))>0)
  502.     {
  503.         if (last)
  504.             len+=4;
  505.         else
  506.             len+=3;
  507.  
  508.         *dest++=(uchar) (len&0xff);
  509.         *dest++=(uchar) (len>>8);
  510.         *dest++=id;
  511.  
  512.         while (*source!='\0')
  513.             *dest++=*source++;
  514.  
  515.         if (last)
  516.             *dest++=0xff;
  517.     }
  518.  
  519.     return(len);
  520. }
  521.  
  522. int wthdr(LzHead *h,FILE *file,int rec,int make,int Case,int unpck)
  523. {
  524.     register uchar *ptr,*s,*n=h->Fname+1;
  525.     register uint len=0;
  526.     register ulong size;
  527.     register _DOSTIME time;
  528.  
  529.     if (make)
  530.     {
  531.         if (flg_k>0 && (UnixArc || flg_s))
  532.         {
  533.             register uchar c,s='\\';
  534.  
  535.             ptr=n;
  536.             while ((c=*ptr++)!='\0')
  537.                 if (c==s)
  538.                     ptr[-1]='/';
  539.  
  540.             if (Case==_PC_CASECONV)
  541.                 strlwr(n);
  542.         }
  543.         else
  544.         {
  545.             yen2slash(n);
  546.  
  547.             if (Case==_PC_CASECONV)
  548.                 strupr(n);
  549.         }
  550.  
  551.         if (flg_k>0)
  552.         {
  553.             if (flg_k<2)
  554.                 s=n+h->Fname[0]+ex_len;
  555.             else
  556.             {
  557.                 uchar path[MAXPATH];
  558.  
  559.                 strncpy(path,n,h->Fname[0]);
  560.                 path[h->Fname[0]]='\0';
  561.  
  562.                 len+=make_ext(&h->Fname[3],get_fname(path),0x01,FAULT);
  563.  
  564.                 if ((s=backpath(path))>path)
  565.                 {
  566.                     s[-1]='\0';
  567.                     len+=make_ext(&h->Fname[len+3],path,0x02,SUCCS);
  568.                 }
  569.  
  570.                 s=&h->Fname[len+3];
  571.             }
  572.  
  573.             if (h->Attr!=0x20 || flg_k==2)
  574.             {
  575.                 len+=5;
  576.                 *s++=5;
  577.                 *s++='\0';
  578.                 *s++=0x40;
  579.                 *s++=h->Attr;
  580.                 *s++='\0';
  581.             }
  582.  
  583.              if (*comment)
  584.              {
  585.                  register uint off=make_ext(s,comment,0x3f,SUCCS);
  586.                 len+=off;
  587.                 s+=off;
  588.             }
  589.  
  590.             *s++='\0';
  591.             *s++='\0';
  592.         }
  593.  
  594.         hdr_len=len;
  595.     }
  596.     else
  597.         len=hdr_len;
  598.  
  599.     if (flg_k==1)
  600.         h->PacSiz+=len;
  601.  
  602.     if (flg_k<2)
  603.         ptr=n+h->Fname[0];
  604.     else
  605.         ptr=h->Fname;
  606.  
  607.     *ptr++=(uchar) (crc&0xff);
  608.     *ptr++=(uchar) (crc>>8);
  609.  
  610.     if (flg_k>0)
  611.     {
  612.         if (UnixArc || flg_s)
  613.             *ptr=(uchar) 'U';
  614.         else
  615.             *ptr=(uchar) 'a';
  616.         h->Attr=0x20;
  617.     }
  618.  
  619.     if (flg_k<2)
  620.     {
  621.         len+=h->HeadSiz;
  622.         h->HeadChk=mksum(h,h->HeadSiz+1);
  623.         len+=2;
  624.     }
  625.     else
  626.     {
  627.         len+=26;
  628.         h->HeadSiz=(uchar) (len&0xff);
  629.         h->HeadChk=(uchar) (len>>8);
  630.     }
  631.  
  632.     size=header_len=len;
  633.  
  634.     if (unpck)
  635.         size+=h->OrgSiz;
  636.     else
  637.         size+=(h->OrgSiz>>1);
  638.  
  639.     ilong(&h->PacSiz);
  640.     ilong(&h->OrgSiz);
  641.  
  642.     time=h->Ftime;
  643.     if (flg_k<2)
  644.         ITIME(h->Ftime);
  645.     else
  646.         dos_2_unixtime((void *) &h->Ftime);
  647.  
  648.     if (make && unpck && size>=bsize)
  649.     {
  650.         if (buffered)
  651.         {
  652.             ShipOut();
  653.             LSeek(file,arcpos0,SEEK_SET);
  654.         }
  655.  
  656.         rec=PAC_NO_BUF;
  657.     }
  658.  
  659.     if (rec==PAC_NO_BUF)
  660.     {
  661.         buffered=0;
  662.         if (fwrite((uchar *) h,7,1,file)!=1 || fwrite((uchar *) h+8,(ulong) len-7,1,file)!=1)
  663.             error(WTERR,arcname,SUCCS);
  664.     }
  665.     else
  666.     {
  667.         if (rec==PAC_INIT_BUF)
  668.         {
  669.             if (file->_cnt && fflush(file))
  670.                 error(WTERR,arcname,SUCCS);
  671.  
  672.             if (!buffered)
  673.                 OpenOut();
  674.             else if (outrec.cnt<=(len+32) || (bsize>size && outrec.cnt<=size))
  675.                 ShipOut();
  676.  
  677.             buffer_start=outrec.ptr;
  678.             buffer_last=(outrec.ptr+=len);
  679.             outrec.cnt-=len;
  680.             buffered=1;
  681.         }
  682.  
  683.         memcpy(buffer_start,h,7);
  684.         memcpy(buffer_start+7,((uchar *) h)+8,len-7);
  685.     }
  686.  
  687.     arcpos1=arcpos0 + len;
  688.  
  689.     ilong(&h->PacSiz);
  690.     ilong(&h->OrgSiz);
  691.     h->Ftime=time;
  692.  
  693.     return(rec);
  694. }
  695.  
  696. void unix2dos(uchar *unx,int rel){    register uchar *u=unx,*d=u,c;
  697.     yen2slash(unx);    if (!strncmp(u,"\\dev\\",5))
  698.     {        u+=5;        if (u[0]!='\0' && (u[1]=='\0' || u[1]=='\\'))
  699.         {
  700.             if (rel)
  701.                 u++;
  702.             else
  703.             {
  704.                 *d++=*u++;
  705.                 *d++=':';
  706.             }
  707.         }
  708.     }
  709.     else if (!strncmp(u,"\\pipe\\",6))
  710.         u+=6;    while ((c=*u++)!='\0')
  711.     {
  712.         if (rel && c==':' && ((d>&unx[1] && d[-2]=='\\') || (d==&unx[1])))
  713.             d=unx;        else            *d++=c;    }
  714.     *d++='\0';
  715. }
  716.  
  717. void yen2slash(uchar *p)
  718. {
  719.     register uchar c,s='/';
  720.  
  721.     while ((c=*p++)!='\0')
  722.         if (c==s)
  723.             p[-1]='\\';
  724. }
  725.  
  726. void Convert_Filename(uchar *dest,uchar *source,int conv)
  727. {
  728.     if (source)
  729.         strcpy(dest,source);
  730.     yen2slash(dest);
  731.  
  732.     if (conv<0)
  733.         Case=case_sensitive(dest);
  734.     else if (conv>0)
  735.         TruncFile(dest);
  736.  
  737.     if (!flg_S && Case==_PC_CASECONV)
  738.         strupr(dest);
  739.     else if (conv<0 && (flg_S==2 || (!flg_S && Case==_PC_CASEINSENS)))
  740.         strupr(dest);
  741. }
  742.  
  743. void unix_2_dostime(void *time)
  744. {
  745.     register _DOSTIME *dostime=(_DOSTIME *) time;
  746.     register struct tm *tm;
  747.  
  748.     ilong((ulong *) time);
  749.     if ((tm=localtime((time_t *) time))!=NULL)
  750.     {
  751.         dostime->time=(uint) ((tm->tm_hour<<11)|(tm->tm_min<<5)|(tm->tm_sec>>1));
  752.         dostime->date=(uint) (((tm->tm_year-80)<<9)|(tm->tm_mon<<5)|tm->tm_mday);
  753.     }
  754.     else
  755.         dostime->time=dostime->date=0;
  756. }
  757.  
  758. void dos_2_unixtime(void *time)
  759. {
  760.     register _DOSTIME *dostime=(_DOSTIME *) time;
  761.     register uint val;
  762.     register struct tm tm,*t=&tm;
  763.  
  764.     val=dostime->time;
  765.     t->tm_sec=(val&31)<<1;
  766.     t->tm_min=(val>>=5)&63;
  767.     t->tm_hour=val>>=6;
  768.  
  769.     val=dostime->date;
  770.     t->tm_mday=val&31;
  771.     t->tm_mon=(val>>=5)&15;
  772.     t->tm_year=(val>>=4)+80;
  773.  
  774.     *((time_t *) time)=mktime(t);
  775.     ilong((ulong *) time);
  776. }
  777.  
  778. uchar *gethdr(FILE *arc,LzHead *h)
  779. {
  780.     uchar exthdr[MAXEXT],fname[MAXPATH];
  781.     register uchar *p;
  782.     register uint extsize;
  783.     register int length;
  784.     register long pos,read;
  785.  
  786.     _gethdr:
  787.     *comment='\0';
  788.     lastarcpos=nextarcpos;
  789.     memset(h,0,sizeof(LzHead));
  790.  
  791.     if (fread((uchar *) h,7,1,arc)!=1 || fread((uchar *) h+8,14,1,arc)!=1)
  792.         goto no_hdr;
  793.  
  794.     if (h->Level>2)
  795.         goto no_hdr;
  796.     else if (h->Level==2)
  797.         h->HeadSiz=HDRSIZ2;
  798.     else if    (h->HeadSiz<MINHDR || h->HeadSiz>sizeof(LzHead))
  799.         goto no_hdr;
  800.  
  801.     read=h->HeadSiz+2;
  802.  
  803.     if (fread((uchar *) h+22,read-21,1,arc)!=1)
  804.         goto no_hdr;
  805.  
  806.     ilong(&h->PacSiz);
  807.     ilong(&h->OrgSiz);
  808.  
  809.     if (h->Level<2)
  810.         ITIME(h->Ftime);
  811.     else
  812.         unix_2_dostime((void *) &h->Ftime);
  813. #if 0
  814.     h->Mtime=h->Ftime;
  815. #endif
  816.  
  817.     lastarclen=read+h->PacSiz;
  818.     pos=lastarcpos+read;
  819.  
  820.     if (h->Level<2)
  821.     {
  822.         if (mksum(h,h->HeadSiz)!=h->HeadChk && mksum(h,h->HeadSiz+1)!=h->HeadChk)
  823.             goto no_hdr;
  824.  
  825.         length=h->Fname[0];
  826.         strncpy(filename,&h->Fname[1],length);
  827.         filename[length++]='\0';
  828.     }
  829.     else
  830.     {
  831.         length=0;
  832.         filename[0]='\0';
  833.     }
  834.  
  835.     p=h->Fname+length;
  836.     h->crc=(uint) *p++;
  837.     h->crc|=(uint) (*p++<<8);
  838.     SystemId=*p++;
  839.  
  840.     has_crc=(flg_chk) ? FAULT : SUCCS;
  841.  
  842.     switch(h->HeadSiz-length)
  843.     {
  844.     case (HDRSIZ0-1-2):
  845.         has_crc=FAULT;
  846.     case (HDRSIZ0-1):
  847.         h->Level=0;
  848.         break;
  849.     default:
  850.         if (h->Level==0)
  851.         {
  852.             if (SystemId==EXTEND_UNIX || SystemId==EXTEND_OS68K)
  853.             {
  854. #if 0
  855.                 memcpy(&h->Mtime,p+1,4);
  856.                 unix_2_dostime((void *) &h->Mtime);
  857. #endif
  858.             }
  859.             else
  860.                 h->Level++;
  861.         }
  862.         break;
  863.     }
  864.  
  865.     if (h->Level>0)
  866.     {
  867.         extsize=(uint) *p++;
  868.         extsize|=(uint) (*p++<<8);
  869.  
  870.         while (extsize>0)
  871.          {
  872.              pos+=extsize;
  873.              if (extsize>MAXEXT)
  874.             {
  875.                 if (sseek(arc,pos-2,0))
  876.                     goto no_hdr;
  877.             }
  878.             else if (fread(exthdr,(length=extsize-2),1,arc)!=1)
  879.                 goto no_hdr;
  880.             else
  881.             {
  882.                 length--;
  883.                 switch (exthdr[0])
  884.                 {
  885.     #if 0
  886.                 case 0:        /* common header */
  887.                     break;
  888.     #endif
  889.                 case 1:        /* filename header */
  890.                 case 2:        /* pathname header */
  891.                     if (length>=pt_name)
  892.                         break;
  893.  
  894.                     strncpy(fname,&exthdr[1],length);
  895.  
  896.                     if ((p=strchr(fname,'\xff'))!=NULL)
  897.                         length=(int) (p-fname);
  898.  
  899.                     fname[length]='\0';
  900.  
  901.                     if (exthdr[0]==1)
  902.                     {
  903.                         p=get_fname(filename);
  904.                         if (((int) (p - filename) + length)<pt_name)
  905.                             strcpy(p,fname);
  906.                     }
  907.                     else if (((int) strlen(filename) + length + 1)<pt_name)
  908.                     {
  909.                         if (fname[length-1]!='\\' && fname[length-1]!='/')
  910.                             strcat(fname,"\\");
  911.  
  912.                         strcat(fname,filename);
  913.                         strcpy(filename,fname);
  914.                     }
  915.                     break;
  916.                 case 0x3f:    /* comment */
  917.                     strncpy(comment,&exthdr[1],length);
  918.                     comment[length]='\0';
  919.  
  920.                     if ((p=strchr(comment,'\xff'))!=NULL)
  921.                         *p='\0';
  922.                     break;
  923.                 case 0x40:    /* file attribute */
  924.                     h->Attr=exthdr[1];
  925.                     break;
  926.     #if 0
  927.                 case 0x50:    /* permission */
  928.                 case 0x51:    /* gid and uid */
  929.                 case 0x52:    /* group name */
  930.                 case 0x53:  /* user name */
  931.                     break;
  932.                 case 0x54:  /* last modified time */
  933.                     memcpy(&h->Mtime,&exthdr[1],4);
  934.                     unix_2_dostime((void *) &h->Mtime);
  935.                     break;
  936.     #endif
  937.                 }
  938.             }
  939.  
  940.             read+=extsize;
  941.             if (h->Level<2)
  942.                 h->PacSiz-=extsize;
  943.             else
  944.                 lastarclen+=extsize;
  945.  
  946.             extsize=Bgetc(arc);
  947.             extsize+=(uint) Bgetc(arc)<<8;
  948.         }
  949.     }
  950.  
  951.     if (strchr("UXHK",SystemId) || strchr(filename,'/'))
  952.     {
  953.         UnixArc=SUCCS;
  954.  
  955.         if (flg_k<=0)
  956.         {
  957.             flg_k=1;
  958.             ex_len=3;
  959.         }
  960.     }
  961.  
  962.     yen2slash(filename);
  963.     unix2dos(strcpy(matchfilename,filename),1);
  964.  
  965.     if (matchfilename[0] && matchfilename[1]==':')
  966.         strcpy(matchfilename,matchfilename+2);
  967.  
  968.     if (matchfilename[0]=='\\' && flg_x==3)
  969.         strcpy(matchfilename,matchfilename+1);
  970.  
  971.     if (!strncmp(matchfilename,".\\",2))
  972.         strcpy(matchfilename,matchfilename+2);
  973.     else if (!strncmp(matchfilename,"..\\",3))
  974.         strcpy(matchfilename,matchfilename+3);
  975.  
  976.     h->Attr&=0x3f;
  977.  
  978.     {
  979.         register int len=(int) strlen(matchfilename) - 1;
  980.  
  981.         if (matchfilename[len]=='\\')
  982.         {
  983.             matchfilename[len]='\0';
  984.             h->Attr=FA_DIR;
  985.         }
  986.         else if (tstID(h->HeadID)==6)
  987.             h->Attr=FA_DIR;
  988.  
  989.         if (h->Attr & FA_DIR)
  990.         {
  991.             if (h->Attr!=FA_DIR)
  992.                 h->Attr&=~FA_DIR;
  993.             else
  994.             {
  995.                 h->OrgSiz=h->PacSiz=0;
  996.                 lastarclen=read;
  997.             }
  998.         }
  999.     }
  1000.  
  1001.     nextarcpos=lastarcpos+lastarclen;
  1002.  
  1003.     if (!flg_S && Case==_PC_CASECONV)
  1004.         strupr(matchfilename);
  1005.  
  1006.     Convert_Filename(dosfilename,matchfilename,1);
  1007.     UnixFile=strcmp(dosfilename,matchfilename);
  1008.  
  1009.     if (flg_S==2 && (!flg_S && Case==_PC_CASEINSENS))
  1010.         strupr(matchfilename);
  1011.  
  1012.     if (!ferror(arc))
  1013.         return(get_fname(matchfilename));
  1014.  
  1015.     no_hdr:
  1016.     if (lastarcpos<(arclen-20))
  1017.     {
  1018.         LSeek(arc,lastarcpos,SEEK_SET);
  1019.  
  1020.         if (search_lzh(arc,NULL,-1))
  1021.         {
  1022.             if (!flg_q)
  1023.             #if GERMAN
  1024.                 puts(" Zerstörte Daten gefunden und Ã¼berlesen");
  1025.             #else
  1026.                 puts(" Garbage found and skipped");
  1027.             #endif
  1028.             garbage++;
  1029.             goto _gethdr;
  1030.         }
  1031.         else if (!flg_q)
  1032.         #if GERMAN
  1033.             printf("Ãœberflüssige Daten am Archivende (%ld Bytes)\n",arclen-lastarcpos);
  1034.         #else
  1035.             printf("Garbage found at the archive-end (%ld bytes)\n",arclen-lastarcpos);
  1036.         #endif
  1037.     }
  1038.  
  1039.     return(NULL);
  1040. }
  1041.  
  1042. int matchpat(uchar *p,register int pat,register int attr)
  1043. {
  1044.     register uchar *name,path[MAXPATH];
  1045.     register int i,k,retcode=FAULT,wild;
  1046.  
  1047.     if (*p=='\0')
  1048.         return(FAULT);
  1049.  
  1050.     if (attr & FA_DIR)
  1051.     {
  1052.         if (flg_f<2)
  1053.         {
  1054.             Nfile++;
  1055.             return(SUCCS);
  1056.         }
  1057.     }
  1058.     else if (flg_f==3)
  1059.         return(FAULT);
  1060.  
  1061.     name=get_fname(p);
  1062.     backpath(strcpy(path,p));
  1063.  
  1064.     for (i=(pat>=0) ? (pat+1) : patno;--i>=0;)
  1065.     {
  1066.         wild=(flg_W) ? flg_W : !travel_file[i];
  1067.  
  1068.         if (flg_p)
  1069.         {
  1070.             if (strcmp(path,travel_path[i]))
  1071.                 continue;
  1072.         }
  1073.         else if (travel_len[i] && strncmp(path,travel_path[i],travel_len[i]))
  1074.             continue;
  1075.  
  1076.         if (all || chk_wild(name,&fileregbuf[travel_file[i]],wild))
  1077.         {
  1078.             for (k=exno;--k>=0;)
  1079.                 if (chk_wild(name,exclude_file[k],0))
  1080.                     break;
  1081.  
  1082.             if (k<0)
  1083.             {
  1084.                 if (pat<0)
  1085.                 {
  1086.                     patcnt[i]++;
  1087.                     retcode=SUCCS;
  1088.                 }
  1089.                 else
  1090.                     return(SUCCS);
  1091.             }
  1092.         }
  1093.  
  1094.         if (pat>=0)
  1095.             break;
  1096.     }
  1097.  
  1098.     if (retcode)
  1099.         Nfile++;
  1100.  
  1101.     return(retcode);
  1102. }
  1103.  
  1104. uint ratio(ulong a,ulong b)
  1105. {
  1106.     register int i;
  1107.  
  1108.     if (!b)
  1109.         return(1000);
  1110.  
  1111.     for (i=0; i<3 && a<0x19999999L; i++)
  1112.         a*=10;
  1113.     for (;i<3;i++)
  1114.         b/=10;
  1115.     a+=b/2;
  1116.     return((uint) (a/b));
  1117. }
  1118.  
  1119. void regfile(uchar *p,uchar *q,_DTA *file,uchar *f)
  1120. {
  1121.     register uchar *s;
  1122.     register filebuf *f0,*f1;
  1123.     register int attr,len;
  1124.     register uchar ch;
  1125.  
  1126.     attr=(oldtos) ? file->dta_attribute^FA_CHANGED : file->dta_attribute;
  1127.     if (attr & FA_DIR)
  1128.         attr=FA_DIR;
  1129.     else
  1130.     {
  1131.         if (flg_arc && !(attr & FA_CHANGED))
  1132.             return;
  1133.         else if (flg_j && file->dta_size==0)
  1134.             return;
  1135.         else if (maxlen>0 && file->dta_size>maxlen)
  1136.             return;
  1137.         else if (cmd=='C' && file->dta_size<=min_len)
  1138.             return;
  1139.     }
  1140.  
  1141.     if (strstr(f,TEMPFILE))
  1142.         return;
  1143.  
  1144.     if (!fbuf)
  1145.     {
  1146.         if ((fbmax=((long) Malloc(-1)))>65536L && flg_L<2)
  1147.             fbmax>>=1;
  1148.         fbuf=fbnxt=Malloc(fbmax);
  1149.  
  1150.         if (!fbuf)
  1151.             error(MEMOVRERR,NULL,SUCCS);
  1152.  
  1153.         *((long *) fbuf)=0l;
  1154.         fblft=(fbmax-=256)-4;
  1155.         fbnxt+=4;
  1156.         fblast=(filebuf *) fbuf;
  1157.     }
  1158.  
  1159.     f1=(filebuf *) fbnxt;
  1160.     strcpy(s=stpcpy(f1->dir,p),f);
  1161.  
  1162.     if (o_dir!=NULL && !strcmp(f1->dir,o_dir))
  1163.         return;
  1164.  
  1165.     f1->time.time=file->dta_time;
  1166.     f1->time.date=file->dta_date;
  1167.  
  1168.     if (flg_N && FTimeToULong(&newer)>FTimeToULong(&f1->time))
  1169.         return;
  1170.  
  1171.     f1->next=NULL;
  1172.     f1->fpos=s-(uchar *) f1;
  1173.     f1->cpos=flg_x ? ((q-p)+f1->dir-(uchar *) f1) : f1->fpos;
  1174.     f1->attr=attr;
  1175.     f1->flag=0;
  1176.     f1->Case=Case;
  1177.     f1->cluster=min_len;
  1178.  
  1179.     if (patno>1 || !flg_x)
  1180.     {
  1181.         f=(uchar *) f1+f1->fpos;
  1182.         f0=(filebuf *) fbuf;
  1183.         ch=*f;
  1184.  
  1185.         while ((f0=f0->next)!=NULL)
  1186.         {
  1187.             p=(uchar *) f0+f0->fpos;
  1188.             if (ch==*p && !strcmp(f,p) && !strcmp((uchar *) f0+f0->cpos,(uchar *) f1+f1->cpos))
  1189.                 return;
  1190.         }
  1191.     }
  1192.  
  1193.     if (fblft<sizeof(filebuf))
  1194.     {
  1195.         ignfile++;
  1196.         return;
  1197.     }
  1198.  
  1199.     len=(int) (strlen(f1->dir)+(f1->dir-(uchar *) f1))+1;
  1200.     len+=len & 1;
  1201.  
  1202.     fblast->next=fbnxt;
  1203.  
  1204.     fblast=(filebuf *) fbnxt;
  1205.     fblft-=len;
  1206.     fbnxt+=len;
  1207.     fbfiles++;
  1208.  
  1209.     if (flg_n!=1 && !(fbfiles & 15))
  1210.     {
  1211.         printf("\b\b\b\b%4d",fbfiles);
  1212.         fflush(stdout);
  1213.     }
  1214. }
  1215.  
  1216. void travel(uchar *p,uchar *q,int pat)
  1217. {
  1218.     _DTA dta,*old;
  1219.     register _DTA *d=&dta;
  1220.     register int done,compare,filesys;
  1221.     register long handle,buf[MAXPATH>>2];
  1222.     register uchar *s,*name;
  1223.     register XATTR *x=&xattr;
  1224.  
  1225.     filesys=(!flg_S && Case==_PC_CASECONV);
  1226.     compare=(flg_S==2 || (!flg_S && Case==_PC_CASEINSENS));
  1227.  
  1228.     if (!_gemdos)
  1229.     {
  1230.         name=(uchar *) &buf[1];
  1231.  
  1232.         if (*p!='\0')
  1233.             handle=Dopendir(p,0);
  1234.         else
  1235.             handle=Dopendir(act_dir,0);
  1236.  
  1237.         if ((handle&0xff000000l)==0xff000000l)
  1238.             return;
  1239.         else
  1240.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1241.     }
  1242.     else
  1243.     {
  1244.         name=d->dta_name;
  1245.  
  1246.         strcat(p,"*.*");
  1247.  
  1248.         old=Fgetdta();
  1249.         Fsetdta(d);
  1250.         done=Fsfirst(p,-1);
  1251.     }
  1252.  
  1253.     s=backpath(p);
  1254.  
  1255.     while (!done)
  1256.     {
  1257.         if (name[0]=='.' && (name[1]=='\0' || (name[1]=='.' && name[2]=='\0')))
  1258.             goto travel_next;
  1259.         else
  1260.         {
  1261.             if (!_gemdos)
  1262.             {
  1263.                 strcpy(s,name);
  1264.                 Fxattr(0,p,(uchar *) x);
  1265.  
  1266.                 d->dta_time=x->ctime;
  1267.                 d->dta_date=x->cdate;
  1268.                 d->dta_size=x->size;
  1269.                 d->dta_attribute=x->attr;
  1270.             }
  1271.         
  1272.             if ((!flg_a && (d->dta_attribute & (FA_HIDDEN|FA_SYSTEM|FA_RDONLY))) || (d->dta_attribute & FA_LABEL))
  1273.                 goto travel_next;
  1274.         }
  1275.  
  1276.         if (d->dta_attribute & FA_DIR)
  1277.         {
  1278.             if (filesys)
  1279.                 strupr(name);
  1280.  
  1281.             if (flg_f>1)
  1282.             {
  1283.                 strcpy(s,name);
  1284.                 if (compare)
  1285.                     strupr(s);
  1286.  
  1287.                 if (matchpat(p,pat,FA_DIR))
  1288.                 {
  1289.                     *s='\0';
  1290.                     regfile(p,q,d,name);
  1291.                 }
  1292.             }
  1293.             else if (flg_f && travel_wild[pat])
  1294.             {
  1295.                 *s='\0';
  1296.                 regfile(p,q,d,name);
  1297.             }
  1298.  
  1299.             if (flg_r && travel_wild[pat])
  1300.             {
  1301.                 strcpy(stpcpy(s,name),"\\");
  1302.  
  1303.                 if (strlen(p)>=pt_name)
  1304.                     message(M_TOOLONGERR,p);
  1305.                 else
  1306.                     travel(p,q,pat);
  1307.             }
  1308.         }
  1309.         else if (flg_f<3)
  1310.         {
  1311.             if (filesys)
  1312.                 strupr(name);
  1313.             strcpy(s,name);
  1314.             if (compare)
  1315.                 strupr(s);
  1316.  
  1317.             if (matchpat(p,pat,0))
  1318.             {
  1319.                 *s='\0';
  1320.                 regfile(p,q,d,name);
  1321.             }
  1322.         }
  1323.  
  1324.         travel_next:
  1325.  
  1326.         if (_gemdos)
  1327.             done=Fsnext();
  1328.         else
  1329.             done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  1330.         *s='\0';
  1331.  
  1332.     }
  1333.  
  1334.     if (_gemdos)
  1335.         Fsetdta(old);
  1336.     else
  1337.         Dclosedir(handle);
  1338. }
  1339.  
  1340. int drive(uchar *path)
  1341. {
  1342.     if (path[0] && path[1]==':')
  1343.     {
  1344.         register int drv=toupper(path[0]);
  1345.  
  1346.         if (__mint && drv=='U')
  1347.         {
  1348.             if (path[2]=='\\' && path[3] && path[4]=='\\')
  1349.                 drv=toupper(path[3]);
  1350.         }
  1351.  
  1352.         if (drv>='A' && drv<='Z')
  1353.             return(drv-'A');
  1354.     }
  1355.  
  1356.     return(Dgetdrv());
  1357. }
  1358.  
  1359. void mklist(void)
  1360. {
  1361.     register _BPB *bpb;
  1362.     register uchar path[MAXPATH],*rel;
  1363.     register int i,new;
  1364.  
  1365.     fbfiles=Nfile=0;
  1366.  
  1367.     for (i=0;i<patno;i++)
  1368.     {
  1369.         if (!flg_q)
  1370.         {
  1371.         #if GERMAN
  1372.             printf("\r Suchmuster : (%d/%d), Dateien gefunden : %4d",i+1,patno,Nfile);
  1373.         #else
  1374.             printf("\r Pattern : (%d/%d), Files matched : %4d",i+1,patno,Nfile);
  1375.         #endif
  1376.             fflush(stdout);
  1377.         }
  1378.  
  1379.         if (!i)
  1380.             new=SUCCS;
  1381.         else
  1382.             new=strcmp(path,travel_path[i]);
  1383.  
  1384.         strcpy(rel=path,travel_path[i]);
  1385.  
  1386.         if (cmd=='C' && new && (bpb=Getbpb(drive(path)))!=NULL)
  1387.             min_len=bpb->clsizb;
  1388.         else
  1389.             min_len=1024;
  1390.  
  1391.         if (pack || flg_X)
  1392.             rel+=strlen(path);
  1393.         else if (travel_rel[i])
  1394.             rel+=travel_rel[i];
  1395.         else
  1396.         {
  1397.             if (*rel && rel[1]==':')
  1398.                 rel+=2;
  1399.  
  1400.             if (*rel=='\\' && flg_x==3)
  1401.                 rel++;
  1402.  
  1403.             if (!strncmp(rel,".\\",2))
  1404.                 rel+=2;
  1405.             else if (!strncmp(rel,"..\\",3))
  1406.                 rel+=3;
  1407.         }
  1408.  
  1409.         if (new)
  1410.         {
  1411.             pt_name=path_conf(path,_PC_PATH_MAX);
  1412.             if (pt_name>MAXPATH)
  1413.                 pt_name=MAXPATH;
  1414.             Case=case_sensitive(path);
  1415.  
  1416.             if (__mint)
  1417.                 _gemdos=(path_conf(path,_PC_NAME_MAX)<=12 && Case==_PC_CASECONV) ? 1 : 0;
  1418.             else
  1419.                 _gemdos=1;
  1420.         }
  1421.  
  1422.         travel(path,rel,i);
  1423.         patcnt[i]=fbfiles-Nfile;
  1424.         Nfile=fbfiles;
  1425.     }
  1426.  
  1427.     Mshrink(fbuf,fbmax-fblft+32);
  1428.  
  1429.     if (!flg_q)
  1430.     {
  1431.         printf("\b\b\b\b%4d\n\n",Nfile);
  1432.         if (ignfile)
  1433.         #if GERMAN
  1434.             printf("Datei-Tabelle voll, %d Datei(en) ignoriert\n",ignfile);
  1435.         #else
  1436.             printf("File table overflow, %d file(s) ignored\n",ignfile);
  1437.         #endif
  1438.     }
  1439. }
  1440.  
  1441. long _proc_size[]={1000000L,
  1442.                    10000000L,
  1443.                    100000000L,
  1444.                    1000000000L};
  1445.  
  1446. void blkdisp(long len,uchar *s,long size)
  1447. {
  1448.     register int i;
  1449.  
  1450.     blocksize=size;
  1451.     blkcnt=(int) ((len+size-1)/size);
  1452.  
  1453.     for (i=0;i<(sizeof(_proc_size)>>2);i++)
  1454.         if (len<_proc_size[i])
  1455.             break;
  1456.  
  1457.     _frozen_str[13]=_frozen_str[21]=(i+'6');
  1458.  
  1459.     if (!flg_n)
  1460.     {
  1461.         register uchar pind[MAXPATH],*p=pind,c=pnt;
  1462.  
  1463.         if (blkcnt>maxblk)
  1464.         {
  1465.             blkcnt=maxblk;
  1466.             blocksize=len/maxblk;
  1467.         }
  1468.         else if (!blkcnt)
  1469.             blkcnt++;
  1470.  
  1471.         for (i=blkcnt;--i>=0;)
  1472.             *p++=c;
  1473.         *p='\0';
  1474.  
  1475.         printf(" %s :    %s\r %s :    ",s,pind,s);
  1476.     }
  1477.     else if (flg_n==2)
  1478.     {
  1479.         memcpy(_proc_str+2,s,8);
  1480.         _proc_str[20]=_proc_str[25]=_frozen_str[13];
  1481.         printf(_proc_str,0,act_len=0,file_len=len);
  1482.     }
  1483.     else if (flg_n==3)
  1484.     {
  1485.         RotInd=0;
  1486.         printf(" %s:   -\b",s);
  1487.     }
  1488.  
  1489.     fflush(stdout);
  1490. }
  1491.  
  1492. void MakeBuffers(void)
  1493. {
  1494.     register long buf,len=0;
  1495.  
  1496.     if (cmdupdate && !flg_u && FlgMethod==5)
  1497.     {
  1498.         if ((buf=(long) malloc(ENCODE5))!=0)
  1499.         {
  1500.             buf=(buf+=63) & (~15L);
  1501.  
  1502.             text=(uchar *) buf;
  1503.             level=(uchar *) (buf+=TEXT);
  1504.             childcount=(uchar *) (buf+=LEVEL);
  1505.             position=(short *) (buf+=CHILDCOUNT);
  1506.             parent=(short *) (buf+=POSITION);
  1507.             prev=(short *) (buf+=PARENT);
  1508.             next=(short *) (buf+=PREV);
  1509.         }
  1510.         else
  1511.             error(MEMOVRERR,NULL,SUCCS);
  1512.     }
  1513.     else if (FlgMethod!=5 || !cmdupdate)
  1514.     {
  1515.         if ((buf=(long) malloc(ENCODE))!=0)
  1516.         {
  1517.             buf=(buf+=63) & (~15L);
  1518.     
  1519.             lson=(int *) buf;
  1520.             rson=(int *) (buf+=LSON);
  1521.             dad=(int *) (buf+=RSON);
  1522.         }
  1523.         else
  1524.             error(MEMOVRERR,NULL,SUCCS);
  1525.     }
  1526.  
  1527.     if (!flg_L)
  1528.     {
  1529.         len=((long) Malloc(-1)>>3) & (~1023l);
  1530.         if (len>MAXBUFFER)
  1531.             len=MAXBUFFER;
  1532.     }
  1533.     else if (flg_L==2)
  1534.     {
  1535.         len=(((long) Malloc(-1)-65536L)>>2) & (~1023l);
  1536.         if (len>MAXBUFFERL2)
  1537.             len=MAXBUFFERL2;
  1538.     }
  1539.  
  1540.     if (len<=BUFFERSIZ || (buf=(long) malloc(((len+=128)<<2)+128))==0)
  1541.     {
  1542.         buf=(long) buffer;
  1543.         len=BUFFERSIZ+128;
  1544.     }
  1545.  
  1546.     buffer_1=(uchar *) ((buf+63) & (~15l));
  1547.     buffer_2=buffer_1+len;
  1548.     buffer_3=buffer_2+len;
  1549.     buffer_gen=buffer_3+len;
  1550.     bsize=len-128;
  1551. }
  1552.  
  1553. void freeze(uchar *p,int attr,int file,int Case)
  1554. {
  1555.     register int rec=PAC_INIT_BUF,unpck=(flg_u || (Hdr2.OrgSiz<=40 && !flg_5));
  1556.     register long arcpos;
  1557.  
  1558.     crc=ship=0;
  1559.  
  1560.     if (!unpck && flg_U && !flg_5 && chk_wild(get_fname(p),unpack,0))
  1561.         unpck=SUCCS;
  1562.  
  1563.     if (FTimeToULong(&arcstamp)<FTimeToULong(&Hdr2.Ftime))
  1564.         arcstamp=Hdr2.Ftime;
  1565.  
  1566.     if (!flg_q)
  1567.     {
  1568.         if (file>0)
  1569.             printf("(%d/%d): ",file,Nfile);
  1570.  
  1571.         if (attr & FA_DIR)
  1572.             printf("%s: Directory\n",p);
  1573.         else
  1574.             puts(p);
  1575.  
  1576.         if (flg_e)
  1577.             get_comment(stdin);
  1578.     }
  1579.  
  1580.     blkdisp(Hdr2.OrgSiz,(unpck || (attr & FA_DIR)) ? "Storing " : "Freezing",(method==5 && !unpck) ? (N*2) : N);
  1581.  
  1582.     if (attr & FA_DIR)
  1583.     {
  1584.         Hdr2.PacSiz=Hdr2.OrgSiz=0;
  1585.         wthdr(&Hdr2,file2,rec,SUCCS,Case,SUCCS);
  1586.         arcpos0=arcpos1;
  1587.         ProcInd();
  1588.     }
  1589.     else
  1590.     {
  1591.         if (!unpck || cmd!='C')
  1592.             rec=wthdr(&Hdr2,file2,rec,SUCCS,Case,unpck);
  1593.  
  1594.         origsize=textsize=Hdr2.OrgSiz;
  1595.  
  1596.         infile=file3;
  1597.         infname=p;
  1598.  
  1599.         if (unpck)
  1600.             codesize=textsize+1;
  1601.         else if (!method)
  1602.             EncodeOld();
  1603.         else if (method==1)
  1604.             Encode();
  1605.         else if (method==5)
  1606.         {
  1607.             init_encode5();
  1608.             encode5();
  1609.             codesize=compsize;
  1610.         }
  1611.  
  1612.         if (flg_backup)
  1613.         {
  1614.             register int new_attr=attr & (~FA_CHANGED);
  1615.             if (attr!=new_attr)
  1616.                 Fattrib(infname,1,(oldtos) ? new_attr^FA_CHANGED : new_attr);
  1617.         }
  1618.  
  1619.         if (!buffered)
  1620.             rec=PAC_NO_BUF;
  1621.  
  1622.         if (codesize>=origsize || (cmd=='C' && ((origsize+min_len-1)/min_len)<=((codesize+header_len+min_len-1)/min_len)))
  1623.         {
  1624.             flg_unpacked=1;
  1625.  
  1626.             if (cmd!='C')
  1627.             {
  1628.                 arcpos=arcpos1 + Hdr2.OrgSiz;
  1629.                 Hdr2.PacSiz=Hdr2.OrgSiz;
  1630.  
  1631.                 if (!flg_4)
  1632.                     memcpy(Hdr2.HeadID,"-lh0-",5);
  1633.  
  1634.                 if (!unpck)
  1635.                 {
  1636.                     if (buffered)
  1637.                     {
  1638.                         shipout();
  1639.                         rec=PAC_NO_BUF;
  1640.                     }
  1641.  
  1642.                     LSeek(file2,arcpos1,SEEK_SET);
  1643.                     LSeek(file3,0l,SEEK_SET);
  1644.                     copyfile(file3,file2,Hdr2.OrgSiz,0,0);
  1645.                 }
  1646.                 else
  1647.                     copyfile(file3,file2,Hdr2.OrgSiz,1,(rec==PAC_NO_BUF) ? 0 : 1);
  1648.             }
  1649.             else
  1650.             {
  1651.                 while ((long) origsize>0)
  1652.                 {
  1653.                     ProcInd();
  1654.                     origsize-=blocksize;
  1655.                 }
  1656.  
  1657.                 Hdr2.PacSiz=Hdr2.OrgSiz;
  1658.                 goto _freeze_end;
  1659.             }
  1660.         }
  1661.         else
  1662.         {
  1663.             arcpos=arcpos1 + codesize;
  1664.             Hdr2.PacSiz=codesize;
  1665.             flg_unpacked=0;
  1666.         }
  1667.  
  1668.         if (rec==PAC_NO_BUF)
  1669.             LSeek(file2,arcpos0,SEEK_SET);
  1670.         else
  1671.             rec=PAC_EXIT_BUF;
  1672.  
  1673.         wthdr(&Hdr2,file2,rec,FAULT,Case,unpck);
  1674.         arcpos0=arcpos;
  1675.         if (cmd!='C' && (rec==PAC_NO_BUF || !buffered))
  1676.             LSeek(file2,arcpos0,SEEK_SET);
  1677.     }
  1678.  
  1679.     _freeze_end:
  1680.     if (flg_n!=1)
  1681.     {
  1682.         memcpy(_frozen_str+2,(flg_unpacked || (attr & FA_DIR)) ? "Stored:   " : "Frozen:   ",10);
  1683.         printf(_frozen_str,Hdr2.OrgSiz,Hdr2.PacSiz,ratio(Hdr2.PacSiz,Hdr2.OrgSiz)/10);
  1684.     }
  1685.  
  1686.     *comment='\0';
  1687. }
  1688.  
  1689. void get_comment(FILE *f)
  1690. {
  1691.     register int len;
  1692.     register uchar *input=comment,*q;
  1693.  
  1694.     if (f==stdin)
  1695.         puts(M_COMMENT);
  1696.  
  1697.     while (fgets(input,255,f))
  1698.     {
  1699.         if ((q=strchr(input,'\r'))!=NULL || (q=strchr(input,'\n'))!=NULL)
  1700.             *q='\0';
  1701.  
  1702.         if ((len=(int) strlen(input))>0 || f!=stdin)
  1703.         {
  1704.             input+=len;
  1705.             *input++='\n';
  1706.             if (!flg_s)
  1707.                 *input++='\r';
  1708.  
  1709.             if ((int) (input-comment)>=MAXCOMMENT)
  1710.                 break;
  1711.         }
  1712.         else
  1713.             break;
  1714.     }
  1715.  
  1716.     if (input>comment)
  1717.     {
  1718.         if (flg_s)
  1719.             input[-1]='\0';
  1720.         else
  1721.             input[-2]='\0';
  1722.     }
  1723.     else
  1724.         *comment='\0';
  1725. }
  1726.  
  1727. void archive_comment(FILE *output)
  1728. {
  1729.     if (com_name)
  1730.     {
  1731.         register FILE *f;
  1732.  
  1733.         if ((f=fopen(com_name,"r"))!=NULL)
  1734.         {
  1735.             get_comment(f);
  1736.             fclose(f);
  1737.         }
  1738.     }
  1739.     else
  1740.         get_comment(stdin);
  1741.  
  1742.     if (*comment)
  1743.     {
  1744.         uchar buf[MAXCOMMENT+256]=COM_ID;
  1745.         strcat(buf,comment);
  1746.  
  1747.         arcpos0=strlen(buf)+1;
  1748.         if (fwrite(buf,arcpos0,1,output)!=1)
  1749.             error(WTERR,arcname,SUCCS);
  1750.  
  1751.         *comment='\0';
  1752.     }
  1753. }
  1754.  
  1755. void copyold(int buf)
  1756. {
  1757.     infname=arcname;
  1758.     if (FTimeToULong(&arcstamp)<FTimeToULong(&Hdr1.Ftime))
  1759.         arcstamp=Hdr1.Ftime;
  1760.     LSeek(file1,lastarcpos,SEEK_SET);
  1761.  
  1762.     if (buf && buffered)
  1763.     {
  1764.         if (outrec.cnt<=lastarclen)
  1765.         {
  1766.             ShipOut();
  1767.             LSeek(file2,arcpos0,SEEK_SET);
  1768.             copyfile(file1,file2,lastarclen,0,0);
  1769.         }
  1770.         else
  1771.             copyfile(file1,file2,lastarclen,0,1);
  1772.     }
  1773.     else
  1774.         copyfile(file1,file2,lastarclen,0,0);
  1775.     arcpos0+=lastarclen;
  1776. }
  1777.  
  1778. int execappend(void)
  1779. {
  1780.     register filebuf *f0;
  1781.     register uchar *q;
  1782.     register int update,in_arc,cnt=0,file=1;
  1783.  
  1784.     f0=(filebuf *) fbuf;
  1785.     q=file1 ? gethdr(file1,&Hdr1) : NULL;
  1786.  
  1787.     for (;;)
  1788.     {
  1789.         update=FAULT;
  1790.  
  1791.         if (q)
  1792.         {
  1793.             in_arc=SUCCS;
  1794.             f0=(filebuf *) fbuf;
  1795.  
  1796.             while ((f0=f0->next)!=NULL)
  1797.             {
  1798.                 if (!f0->flag && strcmp((uchar *) f0+f0->fpos,q)==0)
  1799.                 {
  1800.                     if (flg_I)
  1801.                         strcpy(backpath(incldir),(uchar *) f0+f0->fpos);
  1802.  
  1803.                     if (strcmp((flg_I) ? incldir : (uchar *) f0+f0->cpos,matchfilename)==0)
  1804.                     {
  1805.                         if (!flg_A)
  1806.                             update=SUCCS;
  1807.                         f0->flag=SUCCS;
  1808.                         break;
  1809.                     }
  1810.                 }
  1811.             }
  1812.         }
  1813.         else
  1814.         {
  1815.             in_arc=FAULT;
  1816.  
  1817.             while ((f0=f0->next)!=NULL)
  1818.             {
  1819.                 if (!f0->flag)
  1820.                 {
  1821.                     if (flg_I)
  1822.                         strcpy(backpath(incldir),(uchar *) f0+f0->fpos);
  1823.                     f0->flag=update=SUCCS;
  1824.                     break;
  1825.                 }
  1826.             }
  1827.  
  1828.             if (!f0)
  1829.                 break;
  1830.         }
  1831.  
  1832.         if (!flg_q)
  1833.         {
  1834.             printf("(%d/%d):\r",file,Nfile);
  1835.             fflush(stdout);
  1836.         }
  1837.  
  1838.         if (update && (!in_arc || flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&f0->time))))
  1839.         {
  1840.             if (f0->attr & FA_DIR)
  1841.                 file3=NULL;
  1842.             else if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))==NULL)
  1843.             {
  1844.                 if (in_arc)
  1845.                     copyold(SUCCS);
  1846.                 goto _append_next;
  1847.             }
  1848.  
  1849.             sethdr((flg_I) ? incldir : (uchar *) f0+f0->cpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  1850.             freeze(f0->dir,f0->attr,file,f0->Case);
  1851.             close(file3);
  1852.             cnt++;
  1853.  
  1854.             if (in_arc)
  1855.                 sseek(file1,nextarcpos,1);
  1856.         }
  1857.         else
  1858.             copyold(SUCCS);
  1859.  
  1860.         _append_next:
  1861.         if (q && (q=gethdr(file1,&Hdr1))==NULL)
  1862.             f0=(filebuf *) fbuf;
  1863.  
  1864.         if (update)
  1865.             file++;
  1866.     }
  1867.  
  1868.     return(cnt);
  1869. }
  1870.  
  1871. void delfile(void)
  1872. {
  1873.     filebuf *f0;
  1874.  
  1875.     f0=(filebuf *) fbuf;
  1876.     while ((f0=f0->next)!=NULL)
  1877.     {
  1878.         if (!(f0->attr & FA_DIR))
  1879.             unlink(f0->dir);
  1880.     };
  1881. }
  1882.  
  1883. int search_lzh(FILE *input,FILE *output,int mode)
  1884. {
  1885.     register long len,pos;
  1886.  
  1887.     if (mode<0)
  1888.         pos=ftell(input);
  1889.     else
  1890.         pos=0;
  1891.  
  1892.     _cont_search:
  1893.     if ((len=fread(text_buf,1,4096,input))>0)
  1894.     {
  1895.         register uchar *ptr=text_buf,*last=ptr+len-5,c,s='-';
  1896.  
  1897.         if (mode>=0)
  1898.         {
  1899.             arcpos0=Fseek(0l,input->_file,SEEK_CUR);
  1900.             arclen=Fseek(0l,input->_file,SEEK_END);
  1901.             Fseek(arcpos0,input->_file,SEEK_SET);
  1902.             arcpos0=0;
  1903.         }
  1904.  
  1905.         for (;ptr<last;ptr++)
  1906.             if (*ptr==s && ptr[4]==s)
  1907.             {
  1908.                 c=ptr[1];
  1909.                 if (c=='l' || c=='L' || c=='a' || c=='A')
  1910.                 {
  1911.                     if (ptr>=(text_buf+2))
  1912.                     {
  1913.                         if (output && flg_z)
  1914.                             archive_comment(output);
  1915.  
  1916.                         LSeek(input,nextarcpos=pos+((ptr-2)-text_buf),SEEK_SET);
  1917.                         INIT_TIMER;
  1918.                         return(SUCCS);
  1919.                     }
  1920.                 }
  1921.                 else if (c=='c' && ptr[2]=='o' && ptr[3]=='m')
  1922.                 {
  1923.                     if (output && !flg_z)
  1924.                     {
  1925.                         arcpos0=strlen(ptr)+1;
  1926.                         if (fwrite(ptr,arcpos0,1,output)!=1)
  1927.                             error(WTERR,arcname,SUCCS);
  1928.                     }
  1929.  
  1930.                     if (mode>0 && !flg_q && flg_x && ((cmd!='V' && cmd!='L') || flg_x<2))
  1931.                     {
  1932.                         puts(ptr+5);
  1933.                         new_line();
  1934.                     }
  1935.  
  1936.                     ptr+=strlen(ptr);
  1937.                 }
  1938.             }
  1939.     }
  1940.  
  1941.     if (mode>=0)
  1942.         error(NOFILEERR,arcname,(mode>0) ? 128 : SUCCS);
  1943.     else if (len>0)
  1944.     {
  1945.         pos+=len;
  1946.         goto _cont_search;
  1947.     }
  1948.  
  1949.     return(FAULT);
  1950. }
  1951.  
  1952. int openarc1(long size)
  1953. {
  1954.     back_1=back_2=0;
  1955.  
  1956.     file1=e_fopen(infname=arcname,NULL,"rb",NOARCERR,FAULT);
  1957.     if (file1 && search_lzh(file1,NULL,1))
  1958.     {
  1959.         setvbuf(file1,buffer_1,_IOFBF,size);
  1960.         INIT_TIMER;
  1961.         return(SUCCS);
  1962.     }
  1963.     else
  1964.     {
  1965.         close(file1);
  1966.         return(FAULT);
  1967.     }
  1968. }
  1969.  
  1970. void get_tempname(uchar *path)
  1971. {
  1972.     register uchar *ext;
  1973.  
  1974.     strcat(path,TEMPFILE);
  1975.     ext=path+strlen(path);
  1976.  
  1977.     do
  1978.     {
  1979.         sprintf(ext,"%X",temp());
  1980.     } while (!Fsfirst(path,-1));
  1981. }
  1982.  
  1983. void openbackup1(void)
  1984. {
  1985.     back_1++;
  1986.  
  1987.     backpath(strcpy(backup1,arcname));
  1988.     get_tempname(backup1);
  1989.  
  1990.     if (Frename(0,arcname,infname=backup1))
  1991.         error(RENAMEERR,arcname,SUCCS);
  1992.  
  1993.     file1=e_fopen(backup1,buffer_1,"rb",WTERR,SUCCS);
  1994.     arclen=Fseek(0l,file1->_file,SEEK_END);
  1995.     Fseek(0l,file1->_file,SEEK_SET);
  1996. }
  1997.  
  1998. void openbackup2(void)
  1999. {
  2000.     back_2++;
  2001.  
  2002.     if (Device)
  2003.         strcpy(backup2,arcname);
  2004.     else
  2005.     {
  2006.         if (flg_w)
  2007.             strcpy(backup2,workdir);
  2008.         else
  2009.             backpath(strcpy(backup2,arcname));
  2010.         get_tempname(backup2);
  2011.     }
  2012.  
  2013.     outfile=file2=e_fopen(outfname=backup2,buffer_2,(flg_w) ? "w+b" : "wb",MKTMPERR,SUCCS);
  2014.     INIT_TIMER;
  2015. }
  2016.  
  2017. void stclosearc(FILE *f)
  2018. {
  2019.     if (fflush(f))
  2020.         error(WTERR,arcname,SUCCS);
  2021.  
  2022.     if (flg_t)
  2023.         Fdatime(&arcstamp,f->_file,1);
  2024.  
  2025.     if (fclose(f))
  2026.         error(WTERR,arcname,SUCCS);
  2027. }
  2028.  
  2029. void endofupdate(int cnt)
  2030. {
  2031.     if (file1)
  2032.     {
  2033.         Fdatime(&arcstamp,file1->_file,1);
  2034.         fclose(file1);
  2035.     }
  2036.         
  2037.     tstpat();
  2038.  
  2039.     if (cnt)
  2040.     {
  2041.         if (file1)
  2042.         {
  2043.             if (flg_B)
  2044.             {
  2045.                 register uchar bakname[MAXPATH],*f;
  2046.  
  2047.                 strcpy(bakname,arcname);
  2048.                 if ((f=strrchr(get_fname(bakname),'.'))!=NULL && (arc_ext(f) || f[1]=='\0'))
  2049.                     strcpy(f,".BAK");
  2050.                 else
  2051.                     strcat(bakname,".BAK");
  2052.                 unlink(bakname);
  2053.                 rename(backup1,bakname);
  2054.             }
  2055.             else
  2056.                 unlink(backup1);
  2057.             file1=NULL;
  2058.         }
  2059.  
  2060.         if (arcpos0)
  2061.         {
  2062.             if (fputc(0,file2)==EOF)
  2063.                 error(WTERR,arcname,SUCCS);
  2064.  
  2065.             if (!Device)
  2066.             {
  2067.                 if (flg_w && drive(arcname)!=drive(backup2))
  2068.                 {
  2069.                     if (!flg_q)
  2070.                     #if GERMAN
  2071.                         puts("Kopiere temporäres Archiv...");
  2072.                     #else
  2073.                         puts("Copying Temp to Archive ...");
  2074.                     #endif
  2075.  
  2076.                     file1=e_fopen(outfname=arcname,buffer_1,"wb",MKFILEERR,SUCCS);
  2077.                     LSeek(file2,0l,SEEK_SET);
  2078.  
  2079.                     copying=1;
  2080.                     copyfile(file2,file1,arcpos0+1,0,0);
  2081.                     stclosearc(file1);
  2082.                     copying=0;
  2083.  
  2084.                     close(file2);
  2085.                     unlink(backup2);
  2086.                 }
  2087.                 else
  2088.                 {
  2089.                     stclosearc(file2);
  2090.                     rename(backup2,arcname);
  2091.                 }
  2092.             }
  2093.         }
  2094.         else
  2095.         {
  2096.             close(file2);
  2097.             if (!Device)
  2098.                 unlink(backup2);
  2099.         }
  2100.     }
  2101.     else
  2102.     {
  2103.         close(file2);
  2104.         if (!Device)
  2105.         {
  2106.             unlink(backup2);
  2107.             rename(backup1,arcname);
  2108.         }
  2109.     }
  2110.     file1=file2=NULL;
  2111. }
  2112.  
  2113. void append(void)
  2114. {
  2115.     register int cnt;
  2116.  
  2117.     if (Device)
  2118.         file1=NULL;
  2119.     else if ((file1=fopen(arcname,"rb"))!=NULL)
  2120.     {
  2121.         close(file1);
  2122.         openbackup1();
  2123.     }
  2124.  
  2125.     mklist();
  2126.     if (!Nfile)
  2127.         error(NOFILEERR,NULL,SUCCS);
  2128.  
  2129.     if (flg_u && !flg_n)
  2130.         flg_n++;
  2131.  
  2132.     if (file1)
  2133.         message("Updating archive",arcname);
  2134.     else if (Device)
  2135.         message("Freeze/Store to",arcname);
  2136.     else
  2137.         message("Creating archive",arcname);
  2138.  
  2139.     openbackup2();
  2140.     if (file1)
  2141.         search_lzh(file1,file2,0);
  2142.     else if (flg_z)
  2143.         archive_comment(file2);
  2144.  
  2145.     buffered=0;
  2146.     cnt=execappend();
  2147.     if (buffered)
  2148.     {
  2149.         ShipOut();
  2150.         LSeek(file2,arcpos0,SEEK_SET);
  2151.     }
  2152.  
  2153.     endofupdate(cnt);
  2154.  
  2155.     if (flg_d)
  2156.         delfile();
  2157. }
  2158.  
  2159. void pack_afx(void)
  2160. {
  2161.     register filebuf *f0;
  2162.     register int file=1,tst;
  2163.     register uchar *x;
  2164.  
  2165.     flg_x=3;
  2166.     old_afx=afxonoff(0L);
  2167.  
  2168.     mklist();
  2169.     if (!Nfile)
  2170.         error(NOFILEERR,NULL,SUCCS);
  2171.  
  2172.     FlgMethod=flg_x=0;
  2173.     f0=(filebuf *) fbuf;
  2174.  
  2175.     while ((f0=f0->next)!=NULL)
  2176.     {
  2177.         if ((x=strrchr(get_fname(f0->dir),'.'))!=NULL && (!strcmp(x,".O") || !strcmp(x,".LIB")))
  2178.             obj=SUCCS;
  2179.         else
  2180.             obj=FAULT;
  2181.  
  2182.         if ((tst=test_afx(f0->dir))==0)
  2183.         {
  2184.             if ((file3=e_fopen(f0->dir,buffer_3,"rb",RDERR,FAULT))!=NULL)
  2185.             {
  2186.                 strcpy(backpath(strcpy(backup2,f0->dir)),"__temp__.lzs");
  2187.                 if ((outfile=file2=e_fopen(outfname=backup2,buffer_2,"wb",MKTMPERR,FAULT))!=NULL)
  2188.                 {
  2189.                     arcpos0=buffered=0;
  2190.                     min_len=f0->cluster;
  2191.                     sethdr((uchar *) f0+f0->fpos,f0->attr,&f0->time,&Hdr2,SUCCS);
  2192.                     freeze(f0->dir,f0->attr,file,f0->Case);
  2193.  
  2194.                     if (buffered && !flg_unpacked)
  2195.                         ShipOut();
  2196.     
  2197.                      close(file2);
  2198.                 }
  2199.  
  2200.                 close(file3);
  2201.     
  2202.                  if (!flg_unpacked)
  2203.                 {
  2204.                     unlink(f0->dir);
  2205.                     if (rename(backup2,f0->dir))
  2206.                         error(RENAMEERR,f0->dir,FAULT);
  2207.                 }
  2208.                 else
  2209.                     unlink(backup2);
  2210.             }
  2211.         }
  2212.         else
  2213.         {
  2214.             if (!flg_q)
  2215.             {
  2216.                 printf("(%d/%d): %s\n ",file,Nfile,f0->dir);
  2217.  
  2218.                 switch (tst)
  2219.                 {
  2220.                 case 1:
  2221.                 #if GERMAN
  2222.                     puts("Datei bereits in AFX-Format");
  2223.                 #else
  2224.                     puts("Already in AFX-format");
  2225.                 #endif
  2226.                     break;
  2227.                 case 2:
  2228.                 #if GERMAN
  2229.                     puts("Datei bereits in LHarc-Format");
  2230.                 #else
  2231.                     puts("Already in LHarc-format");
  2232.                 #endif
  2233.                     break;
  2234.                 case 3:
  2235.                 #if GERMAN
  2236.                     puts("Programm-Datei");
  2237.                 #else
  2238.                     puts("Program-file");
  2239.                 #endif
  2240.                     break;
  2241.                 default:
  2242.                 #if GERMAN
  2243.                     puts("Kann Datei nicht lesen");
  2244.                 #else
  2245.                     puts("Read-Error");
  2246.                 #endif
  2247.                 }
  2248.             }
  2249.         }
  2250.         file++;
  2251.     }
  2252.  
  2253.     if (old_afx)
  2254.     {
  2255.         afxonoff(old_afx);
  2256.         old_afx=0;
  2257.     }
  2258. }
  2259.  
  2260. void make_fullpath(uchar *path)
  2261. {
  2262.     register uchar *p=stpcpy(path,basedir);
  2263.  
  2264.     if (flg_x)
  2265.     {
  2266.         if (dosfilename[0]=='\\')
  2267.         {
  2268.             p=path;
  2269.             if (*p && p[1]==':')
  2270.             {
  2271.                 if (__mint && toupper(*p)=='U' && p[2]=='\\' && p[3] && p[4]=='\\')
  2272.                     p+=4;
  2273.                 else
  2274.                     p+=2;
  2275.             }
  2276.         }
  2277.  
  2278.         strcpy(p,dosfilename);
  2279.     }
  2280.     else
  2281.         strcpy(p,get_fname(dosfilename));
  2282. }
  2283.  
  2284. void freshen(void)
  2285. {
  2286.     _DOSTIME time;
  2287.     register uchar path[MAXPATH];
  2288.     register long ok;
  2289.     register int cnt=0,attr;
  2290.  
  2291.     openbackup1();
  2292.     message("Freshening archive",arcname);
  2293.  
  2294.     openbackup2();
  2295.     search_lzh(file1,file2,0);
  2296.     buffered=0;
  2297.  
  2298.     while (gethdr(file1,&Hdr1))
  2299.     {
  2300.         if (!(Hdr1.Attr & FA_DIR) && matchpat(matchfilename,-1,Hdr1.Attr))
  2301.         {
  2302.             make_fullpath(path);
  2303.  
  2304.             if (__mint)
  2305.             {
  2306.                 ok=Fxattr(0,path,(uchar *) &xattr);
  2307.                 time.time=xattr.ctime;
  2308.                 time.date=xattr.cdate;
  2309.                 attr=xattr.attr;
  2310.             }
  2311.             else
  2312.             {
  2313.                 ok=Fsfirst(path,0x07);
  2314.                 time.time=_dta.dta_time;
  2315.                 time.date=_dta.dta_date;
  2316.                 attr=_dta.dta_attribute;
  2317.             }
  2318.  
  2319.             if (!ok && (flg_c || (FTimeToULong(&Hdr1.Ftime)<FTimeToULong(&time))) && (file3=fopen(path,"rb"))!=NULL)
  2320.             {
  2321.                 sethdr(filename,attr,&time,&Hdr2,FAULT);
  2322.                 freeze(path,(oldtos) ? attr^FA_CHANGED : attr,-1,1);
  2323.                 close(file3);
  2324.                 cnt++;
  2325.  
  2326.                 if (flg_d && !(Hdr1.Attr & FA_DIR))
  2327.                     unlink(path);
  2328.  
  2329.                 sseek(file1,nextarcpos,1);
  2330.                 continue;
  2331.             }
  2332.         }
  2333.  
  2334.         copyold(SUCCS);
  2335.     }
  2336.  
  2337.     if (buffered)
  2338.     {
  2339.         ShipOut();
  2340.         LSeek(file2,arcpos0,SEEK_SET);
  2341.     }
  2342.  
  2343.     endofupdate(cnt);
  2344. }
  2345.  
  2346. int Attrib(uchar *p)
  2347. {
  2348.     if (__mint)
  2349.     {
  2350.         if (!Fxattr(0,p,(uchar *) &xattr))
  2351.             return(xattr.attr & FA_DIR);
  2352.     }
  2353.     else if (!Fsfirst(p,-1))
  2354.         return(_dta.dta_attribute & FA_DIR);
  2355.  
  2356.     return(-1);
  2357. }
  2358.  
  2359. int tstdir(uchar *name,int flag)
  2360. {
  2361.     register uchar path[MAXPATH],*p,yn;
  2362.     register int ok;
  2363.  
  2364.     if (!flag && flg_R && stricmp(get_fname(name),get_fname(matchfilename)))
  2365.     {
  2366.         printf("%s (%s):\n%s",name,get_fname(filename),M_ENTERNEW);
  2367.         gets(path);
  2368.  
  2369.         if (path[0]!='\0')
  2370.         {
  2371.             strcpy(backpath(name),get_fname(path));
  2372.             Convert_Filename(name,NULL,0);
  2373.         }
  2374.     }
  2375.  
  2376. Again:
  2377.     if (flag || flg_x)
  2378.     {
  2379.         p=name;
  2380.         if (*p && p[1]==':')
  2381.         {
  2382.             p+=2;
  2383.     
  2384.             if (__mint && toupper(p[-2])=='U' && p[0]=='\\' && p[1] && p[2]=='\\')
  2385.                 p+=2;
  2386.         }
  2387.     
  2388.         if (*p=='\\')
  2389.             p++;
  2390.     
  2391.         if (flag>=0)
  2392.             yn=(flg_m>0 && flg_m<3) ? 'Y' : 'N';
  2393.         else
  2394.             yn='Y';
  2395.     
  2396.         while ((p=strchr(p,'\\'))!=NULL)
  2397.         {
  2398.             memcpy(path,name,p-name);
  2399.             path[p-name]=0;
  2400.     
  2401.             switch(Attrib(path))
  2402.             {
  2403.                 case 0:
  2404.                     error(MKDIRERR,path,(flag<0) ? SUCCS : FAULT);
  2405.                     return(FAULT);
  2406.                 case -1:
  2407.                     if (yn=='N')
  2408.                     {
  2409.                         printf("%s:\n%s",name,M_MKDIR);
  2410.  
  2411.                         if ((yn=get_key("YNA"))=='N')
  2412.                             return(FAULT);
  2413.                         else if (yn=='A')
  2414.                         {
  2415.                             flg_m=(flg_m) ? 1 : 2;
  2416.                             yn='Y';
  2417.                         }
  2418.                     }
  2419.  
  2420.                     if (Dcreate(path))
  2421.                     {
  2422.                         error(MKDIRERR,path,(flag<0) ? SUCCS : FAULT);
  2423.                         return(FAULT);
  2424.                     }
  2425.             }
  2426.  
  2427.             p++;
  2428.         }
  2429.     }
  2430.  
  2431.     if (!flag)
  2432.     {
  2433.         if (__mint)
  2434.         {
  2435.             ok=(int) Fxattr(0,name,&xattr);
  2436.             _dta.dta_attribute=xattr.attr;
  2437.             _dta.dta_date=xattr.cdate;
  2438.             _dta.dta_time=xattr.ctime;
  2439.         }
  2440.         else
  2441.             ok=Fsfirst(name,-1);
  2442.  
  2443.         if (!ok)
  2444.         {
  2445.             if ((_dta.dta_attribute & FA_DIR) && !UnixFile)
  2446.             {
  2447.                 if (!flg_q)
  2448.                     printf("Skipped: %s: Object with same name exists\n",name);
  2449.                 return(FAULT);
  2450.             }
  2451.             else if ((!UnixFile || (flg_m & 0x01)) && !flg_c && (((ulong) _dta.dta_date<<16)|(uint) _dta.dta_time)>=FTimeToULong(&Hdr1.Ftime))
  2452.             {
  2453.                 if (!flg_q)
  2454.                     printf("Skipped: %s: New or same file exists\n",name);
  2455.                 return(FAULT);
  2456.             }
  2457.             else if ((flg_m & 0x01)==0)
  2458.             {
  2459.                 if (UnixFile)
  2460.                     printf("%s (%s):\n%s",name,get_fname(filename),M_OVERWT);
  2461.                 else
  2462.                     printf("%s:\n%s",name,M_OVERWT);
  2463.  
  2464.                 if ((yn=get_key("YNRA"))=='R')
  2465.                 {
  2466.                     printf(M_ENTERNEW);
  2467.                     gets(path);
  2468.  
  2469.                     if (path[0]!='\0')
  2470.                     {
  2471.                         strcpy(backpath(name),get_fname(path));
  2472.                         Convert_Filename(name,NULL,0);
  2473.                         goto Again;
  2474.                     }
  2475.                     else
  2476.                         return(FAULT);
  2477.                 }
  2478.                 else if (yn=='N')
  2479.                     return(FAULT);
  2480.                 else if (yn=='A')
  2481.                     flg_m=(flg_m) ? 1 : 3;
  2482.             }
  2483.  
  2484.             if (_dta.dta_attribute & FA_RDONLY)
  2485.             {
  2486.                 if (_dta.dta_attribute!=Hdr1.Attr)
  2487.                 {
  2488.                     if (!flg_q)
  2489.                         printf("%s: %s\n",name,M_RDONLY);
  2490.                     return(FAULT);
  2491.                 }
  2492.                 else
  2493.                     Fattrib(name,1,_dta.dta_attribute ^ FA_RDONLY);
  2494.             }
  2495.         }
  2496.     }
  2497.  
  2498.     return(SUCCS);
  2499. }
  2500.  
  2501. int tstID(uchar *h)
  2502. {
  2503.     static uchar IDpat[7][6]={"lz4","lz5","lh0","lh1","lh5","afx","lhd"};
  2504.  
  2505.     if (h[0]!='-' || h[4]!='-')
  2506.         return(-1);
  2507.     else
  2508.     {
  2509.         register int m=6;
  2510.  
  2511.         strlwr(++h);
  2512.         while (m>=0 && memcmp(h,IDpat[m],3))
  2513.             m--;
  2514.  
  2515.         return((m==5) ? 1 : m);
  2516.     }
  2517. }
  2518.  
  2519. uchar *Trunc1File(uchar *s,uchar *d)
  2520. {
  2521.     register int l=(int) strlen(s);
  2522.     register uchar c,*t;
  2523.  
  2524.     if (fn_name<=12)
  2525.     {
  2526.         register i,j,k,m;
  2527.  
  2528.         for (i=l;--i>=0;)
  2529.             if (s[i]=='.')
  2530.                 break;
  2531.  
  2532.         if (i<0)
  2533.             m=l;
  2534.         else
  2535.             m=i;
  2536.  
  2537.         t=s;
  2538.         for (j=k=0,t=s;j<=7;j++)
  2539.         {
  2540.             c=*t++;
  2541.             if ((i>0 && k++>i) || c=='\0' || j>=m)
  2542.                 break;
  2543.  
  2544.             if (c>32 && c!='.' && c!=':' && c!='*' && c!='?')
  2545.                 *d++=c;
  2546.             else
  2547.                 j--;
  2548.         }
  2549.  
  2550.         if (i>=0 && fn_name==12)
  2551.         {
  2552.             for (j=4;--j>=0;)
  2553.             {
  2554.                 if ((c=s[i++])=='\0')
  2555.                     break;
  2556.                 if (c>32 && c!=':' && c!='*' && c!='?')
  2557.                     *d++=c;
  2558.             }
  2559.         }
  2560.     }
  2561.     else
  2562.     {
  2563.         strcpy(d,s);
  2564.  
  2565.         if (l<=fn_name)
  2566.             d+=l;
  2567.         else if ((t=strrchr(s,'.'))!=NULL && t>s)
  2568.         {
  2569.             l-=(int) (t-s);
  2570.             l=fn_name-l;
  2571.             if (d[l-1]=='.')
  2572.                 l--;
  2573.  
  2574.             strcpy(d+l,t);
  2575.             d+=fn_name;
  2576.         }
  2577.         else
  2578.             d+=fn_name;
  2579.     }
  2580.  
  2581.     *d='\0';
  2582.     return(d);
  2583. }
  2584.  
  2585. void TruncFile(uchar *s)
  2586. {
  2587.     uchar file[MAXPATH],dest[MAXPATH];
  2588.     register uchar *f=file,*d=dest,*s1=s,c;
  2589.  
  2590.     *d='\0';
  2591.     while ((c=*s++)!='\0')
  2592.     {
  2593.         if (c=='\\' || c==':')
  2594.         {
  2595.             *d='\0';
  2596.             f=Trunc1File(dest,f);
  2597.             *f++=c;
  2598.             *f='\0';
  2599.             d=dest;
  2600.         }
  2601.         else
  2602.             *d++=c;
  2603.     }
  2604.  
  2605.     *d='\0';
  2606.     f=Trunc1File(dest,f);
  2607.     strcpy(s1,file);
  2608. }
  2609.  
  2610. int extract(void)
  2611. {
  2612.     register uchar *p,*q;
  2613.     register int m,cnt=0,succs;
  2614.  
  2615.     if (cmd=='P')
  2616.     {
  2617.         if (pager)
  2618.             message("Extract from",arcname);
  2619.         if (flg_v<2)
  2620.             fprintf(file3,"Extract from: %s\n",arcname);
  2621.     }
  2622.     else
  2623.         message("Extract from",arcname);
  2624.  
  2625.     if (all && exno==0)
  2626.         flg_d=0;
  2627.  
  2628.     if (flg_d)
  2629.     {
  2630.         flg_z=0;
  2631.         openbackup1();
  2632.         openbackup2();
  2633.         if (search_lzh(file1,file2,1)==FAULT)
  2634.         {
  2635.             close(file1);
  2636.             close(file2);
  2637.             unlink(backup2);
  2638.             rename(backup1,arcname);
  2639.             return(0);
  2640.         }
  2641.     }
  2642.     else if (openarc1(bsize)==FAULT)
  2643.         return(0);
  2644.  
  2645.     infile=file1;
  2646.  
  2647.     while (gethdr(file1,&Hdr1))
  2648.     {
  2649.         succs=FAULT;
  2650.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2651.         {
  2652.             if (cmd=='E')
  2653.                 make_fullpath(pathname);
  2654.  
  2655.             if ((m=tstID(Hdr1.HeadID))<0)
  2656.             {
  2657.                 if (!flg_q)
  2658.                     printf("Skipped: %s: Unknown method\n",filename);
  2659.                 skipped++;
  2660.             }
  2661.             else if (cmd=='E' && maxlen>0 && Hdr1.OrgSiz>maxlen)
  2662.             {
  2663.                 if (!flg_q)
  2664.                     printf("Skipped: %s: File too long\n",filename);
  2665.                 skipped++;
  2666.             }
  2667.             else if (cmd=='E' && !flg_a && (Hdr1.Attr & (FA_HIDDEN|FA_SYSTEM)))
  2668.             {
  2669.                 if (!flg_q)
  2670.                     printf("Skipped: %s: Hidden/System File\n",filename);
  2671.                 skipped++;
  2672.             }
  2673.             else if (Hdr1.Attr & FA_DIR)
  2674.             {
  2675.                 if (cmd=='E')
  2676.                 {
  2677.                     if (!flg_q)
  2678.                     {
  2679.                         if (UnixFile)
  2680.                             printf("%s (%s): Directory\n",pathname,filename);
  2681.                         else
  2682.                             printf("%s: Directory\n",pathname);
  2683.  
  2684.                         if (*comment && flg_x)
  2685.                             puts(comment);
  2686.                     }
  2687.  
  2688.                     if ((succs=tstdir(strcat(pathname,"\\"),1))!=0)
  2689.                     {
  2690.                         if (!flg_q)
  2691.                         {
  2692.                             switch(flg_n)
  2693.                             {
  2694.                             case 0:
  2695.                                 printf(" Melted   :    %c\n",star);
  2696.                                 break;
  2697.                             case 2:
  2698.                                 puts(" Melted  : 100%%");
  2699.                                 break;
  2700.                             case 3:
  2701.                                 puts(" Melted  :   -");
  2702.                             }
  2703.                         }
  2704.  
  2705.                         if (flg_d)
  2706.                             message("Deleting",filename);
  2707.                     }
  2708.                 }
  2709.                 else if (!flg_q)
  2710.                     printf("Skipped: %s: Directory\n",filename);
  2711.             }
  2712.             else if (cmd!='E' || tstdir(pathname,0))
  2713.             {
  2714.                 textsize=Hdr1.OrgSiz;
  2715.                 codesize=Hdr1.PacSiz;
  2716.  
  2717.                 cnt++;
  2718.                 crc=0;
  2719.  
  2720.                 p="Melting ";
  2721.                 q="Melted ";
  2722.  
  2723.                 switch(cmd)
  2724.                 {
  2725.                 case 'E':
  2726.                     if (!flg_q)
  2727.                     {
  2728.                         if (UnixFile)
  2729.                             printf("%s (%s)\n",pathname,filename);
  2730.                         else
  2731.                             puts(pathname);
  2732.                     }
  2733.  
  2734.                     if ((file3=e_fopen(outfname=pathname,buffer_3,"wb",WTERR,FAULT))==NULL)
  2735.                         goto _extract_next;
  2736.                     break;
  2737.                 case 'T':
  2738.                     if (!flg_q)
  2739.                         puts(filename);
  2740.                     file3=NULL;
  2741.                     p="Testing ";
  2742.                     q="Tested ";
  2743.                     break;
  2744.                 case 'P':
  2745.                     if (flg_v<2)
  2746.                         fprintf(file3,"<<< %s >>>\n\n",filename);
  2747.                     if (pager && !flg_q)
  2748.                         puts(filename);
  2749.                 }
  2750.  
  2751.                 if (!flg_q && *comment && flg_x)
  2752.                     puts(comment);
  2753.  
  2754.                 if (file3==stdout)
  2755.                     flg_n=1;
  2756.  
  2757.                 blkdisp(textsize,p,(m==4) ? (N*2) : N);
  2758.                 outfile=file3;
  2759.                 succs=SUCCS;
  2760.  
  2761.                 if (m==3)
  2762.                     Decode();
  2763.                 else if (m==1)
  2764.                     DecodeOld();
  2765.                 else if (m==4)
  2766.                     succs=decode_lh5(textsize,codesize);
  2767.                 else
  2768.                     copyfile(infile,outfile,Hdr1.OrgSiz,1,0);
  2769.  
  2770.                 if (cmd=='E')
  2771.                 {
  2772.                     if (fflush(file3))
  2773.                         error(WTERR,outfname,SUCCS);
  2774.  
  2775.                     if ((!flg_i || flg_i==3) && succs)
  2776.                         Fdatime(&Hdr1.Ftime,file3->_file,1);
  2777.  
  2778.                     if (fclose(file3))
  2779.                         error(WTERR,outfname,SUCCS);
  2780.  
  2781.                     if ((!flg_i || flg_i==2) && succs && (Hdr1.Attr!=FA_CHANGED))
  2782.                         Fattrib(pathname,1,(oldtos) ? (Hdr1.Attr^FA_CHANGED) : Hdr1.Attr);
  2783.  
  2784.                     file3=NULL;
  2785.                 }
  2786.                 else if (cmd=='P' && flg_v<2)
  2787.                     fprintf(file3,"\n");
  2788.  
  2789.                 if (succs)
  2790.                 {
  2791.                     if (has_crc && Hdr1.crc!=crc)
  2792.                     {
  2793.                         errorlevel|=2;
  2794.                         succs=FAULT;
  2795.                         c_err++;
  2796.  
  2797.                         if (!flg_q)
  2798.                         {
  2799.                             if (cmd=='P')
  2800.                                 new_line();
  2801.                         #if GERMAN
  2802.                             puts("\r Prüfsummen-Fehler ");
  2803.                         #else
  2804.                             puts("\r CRC error ");
  2805.                         #endif
  2806.                         }
  2807.                     }
  2808.                     else if (!flg_q && (cmd!='P' || pager))
  2809.                     {
  2810.                         if (flg_n!=1)
  2811.                             printf("\r %s\n",q);
  2812.                         if (flg_d)
  2813.                             message("Deleting",filename);
  2814.                     }
  2815.                 }
  2816.             }
  2817.         }
  2818.  
  2819.         _extract_next:
  2820.         if (succs==FAULT && flg_d)
  2821.             copyold(FAULT);
  2822.         else if (sseek(file1,nextarcpos,0))
  2823.             break;
  2824.     }
  2825.  
  2826.     if (!flg_q && (bad_tab || c_err || skipped || garbage))
  2827.         printf("\nBad Tables:    %d\nCRC errors:    %d\nFiles skipped: %d\nCrashed Files: %d\n",bad_tab,c_err,skipped,garbage);
  2828.  
  2829.     if (flg_d)
  2830.         endofupdate(cnt);
  2831.     else
  2832.         close(file1);
  2833.  
  2834.     return(cnt);
  2835. }
  2836.  
  2837. void delete(void)
  2838. {
  2839.     register int cnt=0;
  2840.  
  2841.     if (!patno)
  2842.         error(NOFNERR,NULL,SUCCS);
  2843.  
  2844.     openbackup1();
  2845.  
  2846.     message("Updating archive",arcname);
  2847.  
  2848.     openbackup2();
  2849.     search_lzh(file1,file2,0);
  2850.  
  2851.     while (gethdr(file1,&Hdr1))
  2852.     {
  2853.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2854.         {
  2855.             message("Deleting",filename);
  2856.             cnt++;
  2857.             if (sseek(file1,nextarcpos,0))
  2858.                 break;
  2859.         }
  2860.         else
  2861.             copyold(FAULT);
  2862.     }
  2863.  
  2864.     endofupdate(cnt);
  2865. }
  2866.  
  2867. uchar *sysid(void)
  2868. {
  2869.     switch(SystemId)
  2870.     {
  2871.     case 'M':
  2872.         return("MSDOS");
  2873.     case '2':
  2874.         return("OS/2");
  2875.     case '9':
  2876.         return("OS9");
  2877.     case 'K':
  2878.         return("OS/68K");
  2879.     case '3':
  2880.         return("OS/386");
  2881.     case 'H':
  2882.         return("HUMAN");
  2883.     case 'U':
  2884.         return("UNIX");
  2885.     case 'C':
  2886.         return("CP/M");
  2887.     case 'm':
  2888.         return("Mac");
  2889.     case 'R':
  2890.         return("Runser");
  2891.     case 'A':
  2892.         return("Amiga/Atari");
  2893.     case 'a':
  2894.         return("Atari");
  2895.     case 'F':
  2896.         return("FLEX");
  2897.     case 'X':
  2898.         return("XOSK");
  2899.     case 'T':
  2900.         return("TOWNSOS");
  2901.     default:
  2902.         return("");
  2903.     }
  2904. }
  2905.  
  2906. #ifndef __SHELL__
  2907. void list(void)
  2908. {
  2909.     static uchar attr[7]="rhs-da";
  2910.     register uchar buf[79],*p,*b;
  2911.     register ftime *tim=(ftime *) &Hdr1.Ftime;
  2912.     register int i,j,k;
  2913.     register uint rt;
  2914.     ulong Osize,Psize;
  2915.     int Fno,Dno;
  2916.  
  2917.     Osize=Psize=Fno=Dno=0;
  2918.  
  2919. #if GERMAN
  2920.     printf("Inhalt von: %s\n", arcname);
  2921. #else
  2922.     printf("Listing of archive: %s\n", arcname);
  2923. #endif
  2924.  
  2925.     if (openarc1((drive(arcname)<2) ? 8192L : 1024L)==FAULT)
  2926.         return;
  2927.  
  2928.     if (flg_x<3)
  2929.     {
  2930. #if GERMAN
  2931.         puts("\n Name           Original  Gepackt  Rate   Datum    Zeit     Attr Typ   CRC");
  2932. #else
  2933.         puts("\n Name           Original  Packed   Ratio  Date     Time     Attr Type  CRC");
  2934. #endif
  2935.         puts("--------------  --------  -------- ------ -------- -------- ---- ----- ----");
  2936.     }
  2937.     else
  2938.         puts("\n Name\n--------------");
  2939.  
  2940.     while (gethdr(file1,&Hdr1))
  2941.     {
  2942.         if (matchpat(matchfilename,-1,Hdr1.Attr))
  2943.         {
  2944.             if (flg_x<3)
  2945.             {
  2946.                 rt=ratio(Hdr1.PacSiz,Hdr1.OrgSiz);
  2947.                 sprintf(buf, "              %10lu%10lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d ---w       %04X",
  2948.                     Hdr1.OrgSiz, Hdr1.PacSiz, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  2949.                     tim->day, tim->hour, tim->min, tim->sec * 2,Hdr1.crc);
  2950.                 memcpy(&buf[65],Hdr1.HeadID,5);
  2951.  
  2952.                 for (i=0,j=1;i<6;i++,j<<=1)
  2953.                 {
  2954.                     if (Hdr1.Attr & j)
  2955.                     {
  2956.                         k=attr[i];
  2957.                         if (i<=2)
  2958.                             buf[63-i]=k;
  2959.                         else
  2960.                             buf[60]=k;
  2961.                     }
  2962.                 }
  2963.  
  2964.                 if (flg_x)
  2965.                 {
  2966.                     puts(filename);
  2967.                     p=sysid();
  2968.                     b=buf;
  2969.  
  2970.                     while (*p)
  2971.                         *b++=*p++;
  2972.  
  2973.                     if (flg_x!=2 && *comment)
  2974.                         puts(comment);
  2975.                 }
  2976.                 else
  2977.                 {
  2978.                     register uchar *sl=strrchr(filename,'\\');
  2979.  
  2980.                     if ((Hdr1.Attr & FA_DIR) && sl[1]=='\0')
  2981.                     {
  2982.                         *sl='\0';
  2983.                         p=get_fname(filename);
  2984.                         *sl='\\';
  2985.                     }
  2986.                     else
  2987.                         p=get_fname(filename);
  2988.  
  2989.                     if (p>filename)
  2990.                         buf[0]='+';
  2991.  
  2992.                     if ((i=(int) strlen(p))>15)
  2993.                     {
  2994.                         buf[1]='-';
  2995.                         i=15;
  2996.                     }
  2997.  
  2998.                     memcpy(&buf[2],p,i);
  2999.                 }
  3000.  
  3001.                 puts(buf);
  3002.                 Osize+=Hdr1.OrgSiz;
  3003.                 Psize+=Hdr1.PacSiz;
  3004.             }
  3005.             else
  3006.                 puts(filename);
  3007.  
  3008.             if (Hdr1.Attr & FA_DIR)
  3009.                 Dno++;
  3010.             else
  3011.                 Fno++;
  3012.         }
  3013.  
  3014.         if (sseek(file1,nextarcpos,0))
  3015.             break;
  3016.     }
  3017.  
  3018.     if (Fno || Dno)
  3019.     {
  3020.         if (flg_x<3)
  3021.         {
  3022.             puts("--------------  --------  -------- ------ -------- --------");
  3023.             rt=ratio(Psize, Osize);
  3024.             Fdatime(&arcstamp,file1->_file,0);
  3025.             tim=(ftime *) &arcstamp;
  3026.  
  3027.             printf("  %3d files,  %10lu%10lu %3d.%1d%% %2d-%02d-%02d %2d:%02d:%02d\n  %3d directories\n",
  3028.             Fno, Osize, Psize, rt / 10, rt % 10,(tim->year + 80) % 100, tim->mon,
  3029.             tim->day, tim->hour, tim->min, tim->sec * 2,Dno);
  3030.         }
  3031.         else
  3032.         {
  3033.             puts("--------------");
  3034.         #if GERMAN
  3035.             printf("  %3d Dateien,\n  %3d Ordner\n",Fno,Dno);
  3036.         #else    
  3037.             printf("  %3d files,\n  %3d directories\n",Fno,Dno);
  3038.         #endif
  3039.         }
  3040.     }
  3041.     else
  3042.     #if GERMAN
  3043.         puts("  Keine Datei");
  3044.     #else
  3045.         puts("  no file");
  3046.     #endif
  3047.     close(file1);
  3048. }
  3049. #endif
  3050.  
  3051. void getsw(uchar *p)
  3052. {
  3053.     register uchar s,*q;
  3054.     register int i;
  3055.  
  3056.     while ((s=*p++)!='\0')
  3057.     {
  3058.         q=strchr(swi,s);
  3059.         if (q)
  3060.         {
  3061.             if ((i=(int) (q-swi))<SWI_CNT)
  3062.             {
  3063.                 if (*p=='+')
  3064.                 {
  3065.                     *swipos[i]=1;
  3066.                     p++;
  3067.                 }
  3068.                 else if (*p=='-')
  3069.                 {
  3070.                     *swipos[i]=0;
  3071.                     p++;
  3072.                 }
  3073.                 else if (*p>='0' && *p<='3')
  3074.                     *swipos[i]=*p++ - '0';
  3075.                 else
  3076.                     *swipos[i]=1;
  3077.             }
  3078.  
  3079.             if (flg_q>1)
  3080.             {
  3081.                 new_line();
  3082.                 ptitel++;
  3083.                 flg_q=0;
  3084.             }
  3085.             if (s=='e' || s=='s')
  3086.             {
  3087.                 if (flg_k<=0)
  3088.                 {
  3089.                     flg_k=1;
  3090.                     ex_len=3;
  3091.                 }
  3092.             }
  3093.             else if (s=='r' || s=='X')
  3094.             {
  3095.                 if (!flg_x)
  3096.                     flg_x++;
  3097.             }
  3098.             else if (s=='z')
  3099.             {
  3100.                 if (flg_k<=0)
  3101.                 {
  3102.                     flg_k=1;
  3103.                     ex_len=3;
  3104.                 }
  3105.  
  3106.                 if (*p)
  3107.                 {
  3108.                     com_name=p;
  3109.                     flg_z++;
  3110.                 }
  3111.                 break;
  3112.             }
  3113.             else if (s=='v')
  3114.             {
  3115.                 if (flg_v==3)
  3116.                     flg_q++;
  3117.  
  3118.                 if (*p)
  3119.                 {
  3120.                     if (!flg_v)
  3121.                         flg_v++;
  3122.                     pager=p;
  3123.                 }
  3124.                 break;
  3125.             }
  3126.             else if (s=='M')
  3127.             {
  3128.                 if (isdigit(*p))
  3129.                     maxlen=strtol(p,NULL,10)<<10;
  3130.                 else
  3131.                     maxlen=0;
  3132.                 break;
  3133.             }
  3134.             else if (s=='N')
  3135.             {
  3136.                 for (i=6;--i>=0;)
  3137.                     if (!isdigit(*p++))
  3138.                         break;
  3139.  
  3140.                 if (i<0)
  3141.                 {
  3142.                     flg_N++;
  3143.                     i=(p[-6]-'0')*10 + (p[-5]-'0');
  3144.                     i|=((p[-4]-'0')*10 + (p[-3]-'0'))<<5;
  3145.                     i|=((p[-2]-'0')*10 + (p[-1]-'0') - 80)<<9;
  3146.                     newer.date=i;
  3147.                 }
  3148.                 else
  3149.                 {
  3150.                     flg_N=0;
  3151.                     break;
  3152.                 }
  3153.             }
  3154.             else if (s=='w')
  3155.             {
  3156.                 if (*p)
  3157.                 {
  3158.                     flg_w++;
  3159.                     strcpy(workdir,p);
  3160.                 }
  3161.                 break;
  3162.             }
  3163.             else if (s=='I')
  3164.             {
  3165.                 if (*p)
  3166.                 {
  3167.                     flg_I++;
  3168.                     flg_x=0;
  3169.                     strcpy(incldir,p);
  3170.                 }
  3171.                 break;
  3172.             }
  3173.             else if (s=='U')
  3174.             {
  3175.                 if (*p)
  3176.                 {
  3177.                     flg_U++;
  3178.                     unpack=p;
  3179.                 }
  3180.                 break;
  3181.             }
  3182.             else if (s=='P' && *p)
  3183.             {
  3184.                 star=*p++;
  3185.                 if (*p)
  3186.                     pnt=*p++;
  3187.                 break;
  3188.             }
  3189.             else if (s=='y')
  3190.                 flg_arc++;
  3191.             else if (s=='k')
  3192.             {
  3193.                 if (*p>='0' && *p<='2')
  3194.                     flg_k=*p++ - '0';
  3195.                 else
  3196.                     flg_k=0;
  3197.  
  3198.                 if (!flg_k)
  3199.                     ex_len=flg_e=flg_z=flg_s=0;
  3200.                 else
  3201.                     ex_len=3;
  3202.             }
  3203.             else if (s=='b')
  3204.                 flg_backup++;
  3205.             else if (s=='5')
  3206.             {
  3207.                 flg_5=1;
  3208.                 flg_u=0;
  3209.                 FlgMethod=5;
  3210.             }
  3211.             else if (s=='4')
  3212.             {
  3213.                 flg_5=0;
  3214.                 flg_u=flg_4=1;
  3215.             }
  3216.             else if (s=='l')
  3217.             {
  3218.                 flg_5=flg_u=0;
  3219.                 FlgMethod=0;
  3220.             }
  3221.             else if (s=='o')
  3222.             {
  3223.                 flg_5=flg_u=0;
  3224.                 FlgMethod=1;
  3225.             }
  3226.             else if (s=='u')
  3227.             {
  3228.                 flg_u=1;
  3229.                 flg_5=flg_4=0;
  3230.             }
  3231.         }
  3232.         else if (s=='?')
  3233.         {
  3234.         #ifndef __SHELL__
  3235.             if (!ptitel)
  3236.             {
  3237.                 puts(title_x);
  3238.                 ptitel=1;
  3239.             }
  3240.  
  3241.             puts(use_1);
  3242.             puts(use_2);
  3243.             puts(use_3);
  3244.         #endif
  3245.         }
  3246.         else
  3247.             break;
  3248.     }
  3249.  
  3250.     if (flg_q)
  3251.     {
  3252.         flg_n=flg_m=1;
  3253.         flg_e=flg_z=flg_h=flg_R=0;
  3254.     }
  3255.     else if (i_handle>0)
  3256.     {
  3257.         flg_m=1;
  3258.         flg_R=0;
  3259.     }
  3260. }
  3261.  
  3262. int tstsw(uchar *p)
  3263. {
  3264.     register uchar s,*q;
  3265.     register int i;
  3266.  
  3267.     while ((s=*p++)!='\0')
  3268.     {
  3269.         q=strchr(swi,s);
  3270.         if (q)
  3271.         {
  3272.             if (((int) (q-swi))<SWI_CNT)
  3273.                 if (*p=='+' || *p=='-' || (*p>='0' && *p<='3'))
  3274.                     p++;
  3275.  
  3276.             switch (s)
  3277.             {
  3278.             case 'w':
  3279.             case 'z':
  3280.             case 'U':
  3281.             case 'I':
  3282.             case 'v':
  3283.                 return(SUCCS);
  3284.             case 'M':
  3285.                 return(isdigit(*p));
  3286.             case 'N':
  3287.                 for (i=6;--i>=0;)
  3288.                     if (!isdigit(*p++))
  3289.                         return(FAULT);
  3290.                 break;
  3291.             case 'P':
  3292.                 if (*p)
  3293.                     p++;
  3294.                 if (*p)
  3295.                     p++;
  3296.                 return((*p!='\0') ? FAULT : SUCCS);
  3297.             case 'k':
  3298.                 if (*p>='0' && *p<='2')
  3299.                     p++;
  3300.             }
  3301.         }
  3302.         else if (s!='?')
  3303.             return(FAULT);
  3304.     }
  3305.  
  3306.     return(SUCCS);
  3307. }
  3308.  
  3309. void executecmd(void)
  3310. {
  3311.     register int cnt;
  3312.  
  3313.     INIT_TIMER;
  3314.  
  3315.     switch(cmd)
  3316.     {
  3317.     case 'M':
  3318.         flg_d=1;
  3319.     case 'A':
  3320.         flg_c++;
  3321.     case 'U':
  3322.         flg_chk=0;
  3323.         if (cmd=='U')
  3324.             flg_A=0;
  3325.         append();
  3326.         break;
  3327.     case 'C':
  3328.         flg_X=flg_f=flg_e=flg_z=flg_d=flg_backup=flg_u=flg_4=flg_5=flg_I=0;
  3329.         if (flg_k==2)
  3330.             flg_k=ex_len=0;
  3331.         pack_afx();
  3332.         break;
  3333.     case 'R':
  3334.     case 'F':
  3335.         flg_chk=flg_f=0;
  3336.         freshen();
  3337.         break;
  3338.     case 'P':
  3339.         if (pager==NULL)
  3340.         {
  3341.             file3=stdout;
  3342.             extract();
  3343.         }
  3344.         else
  3345.         {
  3346.             if (flg_w)
  3347.                 strcpy(pathname,workdir);
  3348.             else
  3349.                 backpath(strcpy(pathname,arcname));
  3350.             get_tempname(pathname);
  3351.  
  3352.             file3=e_fopen(outfname=pathname,buffer_3,"wb",MKTMPERR,SUCCS);
  3353.             cnt=extract();
  3354.             if (fclose(file3))
  3355.                 error(WTERR,outfname,SUCCS);
  3356.             file3=NULL;
  3357.             
  3358.             if (cnt)
  3359.             {
  3360.                 uchar buffer[127]="*";
  3361.                 strncat(buffer,pathname,125);
  3362.                 Pexec(0,pager,buffer,NULL);
  3363.             }
  3364.  
  3365.             unlink(pathname);
  3366.         }
  3367.         break;
  3368.     case 'X':
  3369.         cmd='E';
  3370.     case 'T':
  3371.     case 'E':
  3372.         flg_v=flg_z=0;
  3373.         extract();
  3374.         break;
  3375. #ifndef __SHELL__
  3376.     case 'V':
  3377.         if (!flg_x)
  3378.             flg_x++;
  3379.     case 'L':
  3380.         flg_chk=0;
  3381.         list();
  3382.         break;
  3383. #endif
  3384.     case 'D':
  3385.         flg_chk=0;
  3386.         if (!flg_f)
  3387.             flg_f=2;
  3388.         delete();
  3389. #ifndef __SHELL__
  3390.         break;
  3391.     case 'S':
  3392.         if (!flg_q)
  3393.             puts("Self-Extracting-Files: NOT YET IMPLEMENTED !\7");
  3394.         errorlevel|=64;
  3395.         lha_exit();
  3396. #endif
  3397.     }
  3398.  
  3399.     EXIT_TIMER;
  3400.     if (!flg_q)
  3401.         new_line();
  3402. }
  3403.  
  3404. void OneNewFile(uchar *p)
  3405. {
  3406.     register uchar *s;
  3407.     register int len;
  3408.  
  3409.     if ((s=strpbrk(p,"\n"))!=NULL)
  3410.         *s='\0';
  3411.  
  3412.     if ((len=(int) strlen(p)-1)<0)
  3413.         return;
  3414.  
  3415.     if (!patno && !basedir[0] && !cmdlist && (p[len]=='\\' || p[len]==':'))
  3416.         slash(strcpy(basedir,p),1);
  3417.     else if (*p!=EXCLUDE && *p!='~')
  3418.     {
  3419.         if (patno>=MAX_PAT || (fileptr-fileregbuf+strlen(get_fname(p)))>=(FILEBUFSIZ-1))
  3420.             message(M_FILETAB,p);
  3421.         else
  3422.         {
  3423.             travel_file[patno]=travel_rel[patno]=0;
  3424.  
  3425.             while (((s=strstr(p,"\\;"))!=NULL || (s=strstr(p,";\\"))!=NULL))
  3426.             {
  3427.                 if (*s=='\\')
  3428.                     s++;
  3429.                 strcpy(s,s+1);
  3430.                 if (*s=='\\')
  3431.                     s++;
  3432.                 travel_rel[patno]=s-p;
  3433.             }
  3434.  
  3435.             strcpy(fileptr,s=get_fname(p));
  3436.             *s='\0';
  3437.  
  3438.             if (*fileptr=='\0')
  3439.             {
  3440.                 travel_wild[patno]=SUCCS;
  3441.  
  3442.                 if (slash(p,-1))
  3443.                 {
  3444.                     register uchar path[MAXPATH];
  3445.  
  3446.                     slash(strcpy(path,p),1);
  3447.                     if ((p=strdup(path))==NULL)
  3448.                         error(MEMOVRERR,NULL,SUCCS);
  3449.                 }
  3450.             }
  3451.             else if (patno>0 && travel_rel[patno]==travel_rel[patno-1] && !strcmp(p,travel_path[patno-1]))
  3452.             {
  3453.                 if (travel_file[patno-1]>0)
  3454.                 {
  3455.                     travel_wild[patno-1]|=wildcard(fileptr);
  3456.                     fileptr[-1]=',';
  3457.                     while (*fileptr++);
  3458.                 }
  3459.                 return;
  3460.             }
  3461.             else
  3462.             {
  3463.                 travel_file[patno]=(int) (fileptr-fileregbuf);
  3464.                 travel_wild[patno]=wildcard(fileptr);
  3465.                 while (*fileptr++);
  3466.             }
  3467.  
  3468.             travel_path[patno]=p;
  3469.             travel_len[patno++]=(int) strlen(p);
  3470.         }
  3471.     }
  3472.     else if (*++p!='\0')
  3473.     {
  3474.         if (exno>=MAX_EXCLD)
  3475.             message(M_FILETAB,p);
  3476.         else
  3477.             exclude_file[exno++]=get_fname(p);
  3478.     }
  3479. }
  3480.  
  3481. void newfile(uchar *p)
  3482. {
  3483.     if (*p=='&' || *p==FILE_LIST)
  3484.     {
  3485.         register FILE *f;
  3486.  
  3487.         if (p[1]=='-' && p[2]=='\0')
  3488.             f=stdin;
  3489.         else
  3490.             f=fopen(p+1,"r");
  3491.  
  3492.         if (f!=NULL)
  3493.         {
  3494.             register uchar file[MAXPATH],*space;
  3495.  
  3496.             if (f==stdin)
  3497.                 puts(M_PATH);
  3498.  
  3499.             while (fgets(file,MAXPATH-1,f))
  3500.             {
  3501.                 space=file;
  3502.                 while (*space==' ')
  3503.                     space++;
  3504.                 strcpy(file,space);
  3505.  
  3506.                 space=strchr(file,' ');
  3507.                 if (space)
  3508.                     *space=0;
  3509.  
  3510.                 Convert_Filename(file,NULL,-1);
  3511.                 if (file[0]=='&')
  3512.                 {
  3513.                     if (strcmp("&-",file))
  3514.                         newfile(file);
  3515.                 }
  3516.                 else if (file[0]!='\r' && file[0]!='\n')
  3517.                 {
  3518.                     if ((space=strdup(file))==NULL)
  3519.                         error(MEMOVRERR,NULL,SUCCS);
  3520.                     OneNewFile(space);
  3521.                 }
  3522.                 else if (f==stdin)
  3523.                     break;
  3524.             }
  3525.  
  3526.             if (f!=stdin)
  3527.                 close(f);
  3528.         }
  3529.     }
  3530.     else
  3531.         OneNewFile(p);
  3532. }
  3533.  
  3534. void copyfile(FILE *Source,FILE *Dest,long size,int crcflg,int bufflg)
  3535. {
  3536.     register long n,block;
  3537.  
  3538.     if (bufflg)
  3539.         Dest=NULL;
  3540.  
  3541.     if (crcflg)
  3542.         crc=0;
  3543.  
  3544.     if (!crcflg || blocksize>bsize || flg_n==1)
  3545.         block=bsize;
  3546.     else
  3547.         block=blocksize;
  3548.  
  3549.     while (size>0)
  3550.     {
  3551.         n=block>size ? size : block;
  3552.         if (fread((bufflg) ? outrec.ptr : buffer_gen,n,1,Source)!=1)
  3553.             error(RDERR,infname,SUCCS);
  3554.  
  3555.         if (crcflg)
  3556.         {
  3557.             if (!flg_chk)
  3558.                 block_crc(n,(bufflg) ? outrec.ptr : buffer_gen);
  3559.             ProcInd();
  3560.         }
  3561.  
  3562.         if (Dest && fwrite(buffer_gen,n,1,Dest)!=1)
  3563.             error(WTERR,outfname,SUCCS);
  3564.  
  3565.         if (bufflg)
  3566.         {
  3567.             outrec.ptr+=n;
  3568.             outrec.cnt-=n;
  3569.         }
  3570.  
  3571.         size-=n;
  3572.     }
  3573.  
  3574.     if (ferror(Source))
  3575.         error(RDERR,infname,SUCCS);
  3576. }
  3577.  
  3578. void EncodeOld(void)
  3579. {
  3580.     register uchar code_buf[34],*code=code_buf,*ptr,*tbuf=text_buf;
  3581.     register int i,r,s=0,m=N-1,c,last_match_length;
  3582.     ulong printcount;
  3583.     uchar mask=1;
  3584.     int    len;
  3585.  
  3586.     printcount=textsize=0;
  3587.     InitTree();
  3588.  
  3589.     *code++=0;
  3590.     for (i=r=(N-F),ptr=tbuf;--i>=0;)
  3591.         *ptr++=' ';
  3592.  
  3593.     for (i=0;i<F && (c=crc_getc(infile))!=EOF;i++)
  3594.         *ptr++=c;
  3595.  
  3596.     textsize=(len=i);
  3597.     if (!textsize)
  3598.         return;
  3599.  
  3600.     for (i=1;i<=F;i++)
  3601.         InsertONode(r - i);
  3602.     InsertONode(r);
  3603.  
  3604.     do
  3605.     {
  3606.         if (match_length>len)
  3607.             match_length=len;
  3608.  
  3609.         if (match_length <=THRESHOLD)
  3610.         {
  3611.             match_length=1;
  3612.             code_buf[0]|=mask;
  3613.             *code++=tbuf[r];
  3614.         }
  3615.         else
  3616.         {
  3617.             *code++=(uchar) match_position;
  3618.             *code++=(uchar) (((match_position >> 4) & 0xf0) | (match_length - (THRESHOLD + 1)));
  3619.         }
  3620.  
  3621.         if (!(mask<<=1))
  3622.         {
  3623.             i=(int) (code - code_buf);
  3624.             ptr=(code=code_buf);
  3625.  
  3626.             while (--i>=0)
  3627.                 buf_putc(*ptr++);
  3628.  
  3629.             *code++=0;
  3630.             mask=1;
  3631.         }
  3632.  
  3633.         last_match_length=match_length;
  3634.         for (i=0;i<last_match_length && (c=crc_getc(infile))!=EOF;i++)
  3635.         {
  3636.             DeleteONode(s);
  3637.             tbuf[s]=c;
  3638.             if (s < F - 1)
  3639.                 tbuf[s + N]=c;
  3640.             s=(++s) & m;
  3641.             r=(++r) & m;
  3642.             InsertONode(r);
  3643.         }
  3644.  
  3645.         if ((textsize+=i)>printcount)
  3646.         {
  3647.             ProcInd();
  3648.             printcount+=blocksize;
  3649.         }
  3650.  
  3651.         while (i<last_match_length)
  3652.         {
  3653.             DeleteONode(s);
  3654.             s=(++s) & m;
  3655.             r=(++r) & m;
  3656.             if (--len)
  3657.                 InsertONode(r);
  3658.             i++;
  3659.         }
  3660.     } while (len>0);
  3661.  
  3662.     if ((i=(int) (code - code_buf))>1)
  3663.     {
  3664.         ptr=code_buf;
  3665.         while (--i>=0)
  3666.             buf_putc(*ptr++);
  3667.     }
  3668.  
  3669.     if (!buffered)
  3670.         shipout();
  3671. }
  3672.  
  3673. void DecodeOld(void)
  3674. {
  3675.     register int i,k,r=N-F,c=0x2020,m=N-1,*tbuf=(int *) text_buf;
  3676.     register uint crcr=crc;
  3677.     long todo=codesize,done=blocksize;
  3678.     uint flags=0;
  3679.  
  3680.     if (outfile)
  3681.         OpenOut();
  3682.     for (k=(N-F)>>1;--k>=0;)
  3683.         *tbuf++=c;
  3684.  
  3685.     for (;;)
  3686.     {
  3687.         if (!((flags>>=1) & 256))
  3688.         {
  3689.             c=Bgetc(infile);
  3690.             if (todo--==0)
  3691.                 break;
  3692.             flags=c|0xff00;
  3693.         }
  3694.  
  3695.         if (todo--==0)
  3696.             break;
  3697.  
  3698.         if (flags & 1)
  3699.         {
  3700.             c=Bgetc(infile);
  3701.             if (outfile)
  3702.                 buf_putc(c);
  3703.             set_crc(crcr,c);
  3704.  
  3705.             text_buf[r++]=c;
  3706.             r&=m;
  3707.  
  3708.             if (done--==0)
  3709.             {
  3710.                 ProcInd();
  3711.                 done=blocksize;
  3712.             }
  3713.         }
  3714.         else
  3715.         {
  3716.             i=Bgetc(infile);
  3717.             if (todo--==0)
  3718.                 break;
  3719.  
  3720.             i|=(((k=Bgetc(infile)) & 0xf0)<<4);
  3721.             k=(k & 0x0f) + (THRESHOLD+1);
  3722.  
  3723.             for (;--k>=0;i++)
  3724.             {
  3725.                 c=text_buf[i & m];
  3726.                 if (outfile)
  3727.                     buf_putc(c);
  3728.                 set_crc(crcr,c);
  3729.  
  3730.                 text_buf[r++]=c;
  3731.                 r&=m;
  3732.  
  3733.                 if (done--==0)
  3734.                 {
  3735.                     ProcInd();
  3736.                     done=blocksize;
  3737.                 }
  3738.             }
  3739.         }
  3740.     }
  3741.  
  3742.     if (outfile)
  3743.         shipout();
  3744.     ProcInd();
  3745.     crc=crcr;
  3746. }
  3747.  
  3748. int fread_crc(uchar *p,int n,FILE *f)
  3749. {
  3750.     n=(int) fread(p,1,n,f);
  3751.     if (ferror(f))
  3752.         error(RDERR,infname,SUCCS);
  3753.     block_crc(n,p);
  3754.     return(n);
  3755. }
  3756.  
  3757. void count_t_freq(void)
  3758. {
  3759.     register int i,k,n;
  3760.     register ushort *tfreq,tf0,tf1;
  3761.     register uchar *clen;
  3762.  
  3763.     for (i=NT,tfreq=t_freq,k=0;--i>=0;)
  3764.         *tfreq++=k;
  3765.  
  3766.     clen=&c_len[n=NC];
  3767.     while (*--clen==0 && --n>=0);
  3768.  
  3769.     i=tf0=tf1=0;
  3770.     clen=c_len;
  3771.     tfreq=t_freq;
  3772.  
  3773.     while (i<n)
  3774.     {
  3775.         i++;
  3776.         if ((k=*clen++)==0)
  3777.         {
  3778.             k=1;
  3779.             while (i<n && *clen==0)
  3780.             {
  3781.                 clen++;
  3782.                 k++;
  3783.                 i++;
  3784.             }
  3785.  
  3786.             if (k<=2)
  3787.                 tf0+=k;
  3788.             else if (k<=18)
  3789.                 tf1++;
  3790.             else if (k==19)
  3791.             {
  3792.                 tf0++;
  3793.                 tf1++;
  3794.             }
  3795.             else
  3796.                 tfreq[2]++;
  3797.         }
  3798.         else
  3799.             tfreq[k+2]++;
  3800.     }
  3801.  
  3802.     tfreq[0]+=tf0;
  3803.     tfreq[1]+=tf1;
  3804. }
  3805.  
  3806. void write_pt_len(register int n,int nbit,register int i_special)
  3807. {
  3808.     register uchar *ptlen;
  3809.     register int i,k,c=3;
  3810.  
  3811.     ptlen=&pt_len[n];
  3812.     while (*--ptlen==0 && --n>=0);
  3813.  
  3814.     putbits(nbit,n);
  3815.  
  3816.     i=0;
  3817.     ptlen=pt_len;
  3818.     while (i<n)
  3819.     {
  3820.         i++;
  3821.         if ((k=*ptlen++)<=6)
  3822.             putbits(3,k);
  3823.         else
  3824.         {
  3825.             k-=c;
  3826.             putbits(k,(1U<<k)-2);
  3827.         }
  3828.  
  3829.         if (i==i_special)
  3830.         {
  3831.             while (i<6 && *ptlen==0)
  3832.             {
  3833.                 ptlen++;
  3834.                 i++;
  3835.             }
  3836.  
  3837.             putbits(2,(i-c) & c);
  3838.         }
  3839.     }
  3840. }
  3841.  
  3842. void write_c_len(void)
  3843. {
  3844.     register int i,k,n;
  3845.     register uchar l0=pt_len[0],*clen;
  3846.     register ushort c0=pt_code[0],c1=pt_code[1];
  3847.  
  3848.     clen=&c_len[n=NC];
  3849.     while (*--clen==0 && --n>=0);
  3850.  
  3851.     putbits(CBIT,n);
  3852.  
  3853.     i=0;
  3854.     clen=c_len;
  3855.     while (i<n)
  3856.     {
  3857.         i++;
  3858.         if ((k=*clen++)==0)
  3859.         {
  3860.             k=1;
  3861.             while (i<n && *clen==0)
  3862.             {
  3863.                 clen++;
  3864.                 k++;
  3865.                 i++;
  3866.             }
  3867.  
  3868.             switch (k)
  3869.             {
  3870.             case 2:
  3871.                 putbits(l0,c0);
  3872.             case 1:
  3873.                 putbits(l0,c0);
  3874.                 break;
  3875.             case 19:
  3876.                 putbits(l0,c0);
  3877.                 putbits(pt_len[1],c1);
  3878.                 putbits(4,15);
  3879.                 break;
  3880.             default:
  3881.                 if (k<=18)
  3882.                 {
  3883.                     putbits(pt_len[1],c1);
  3884.                     putbits(4,k-3);
  3885.                 }
  3886.                 else
  3887.                 {
  3888.                     putbits(pt_len[2],pt_code[2]);
  3889.                     putbits(CBIT,k-20);
  3890.                 }
  3891.             }
  3892.         }
  3893.         else
  3894.             putbits(pt_len[k+2],pt_code[k+2]);
  3895.     }
  3896. }
  3897.  
  3898. void start_huf(void)
  3899. {
  3900.     register ushort *p,v=0;
  3901.     register int i;
  3902.  
  3903.     text_buf[0]=v;
  3904.     for (i=NC,p=c_freq;--i>=0;)
  3905.         *p++=v;
  3906.  
  3907.     for (i=NP,p=p_freq; --i>=0;)
  3908.         *p++=v;
  3909.  
  3910.     subbitbuf=v;
  3911.     bitcount=CHAR_BIT;
  3912. }
  3913.  
  3914. void end_huf(void)
  3915. {
  3916.     send_block();
  3917.     putbits(CHAR_BIT-1,0);
  3918. }
  3919.  
  3920. int read_pt_len(int nn,int nbit,int i_special)
  3921. {
  3922.     register uchar *ptlen=pt_len;
  3923.     register int n;
  3924.  
  3925.     if ((n=getbits(nbit))==0)
  3926.     {
  3927.         register ushort *table=pt_table,c;
  3928.  
  3929.         for (n=nn,c=0;--n>=0;)
  3930.             *ptlen++=c;
  3931.         for (n=256,c=getbits(nbit);--n>=0;)
  3932.             *table++=c;
  3933.     }
  3934.     else
  3935.     {
  3936.         register int c,i=0;
  3937.         register uint mask,bibu;
  3938.  
  3939.         while (i<n)
  3940.         {
  3941.             bibu=bitbuf;
  3942.             if ((c=bibu>>13)==7)
  3943.             {
  3944.                 mask=1U<<12;
  3945.                 while (mask&bibu)
  3946.                 {
  3947.                     mask>>=1;
  3948.                     c++;
  3949.                 }
  3950.             }
  3951.  
  3952.             fillbuf((c<7) ? 3 : c-3);
  3953.             *ptlen++=c;
  3954.  
  3955.             i++;
  3956.             if (i==i_special)
  3957.             {
  3958.                 i+=(c=getbits(2));
  3959.                 mask=0;
  3960.                 while (--c>=0)
  3961.                     *ptlen++=mask;
  3962.             }
  3963.         }
  3964.  
  3965.         c=0;
  3966.         n=nn;
  3967.         while (i<n)
  3968.         {
  3969.             *ptlen++=c;
  3970.             i++;
  3971.         }
  3972.  
  3973.         if (!make_table(n,pt_len,8,pt_table))
  3974.             return(FAULT);
  3975.     }
  3976.  
  3977.     return(SUCCS);
  3978. }
  3979.  
  3980. int read_c_len(void)
  3981. {
  3982.     register uchar *clen=c_len;
  3983.     register int n,i;
  3984.  
  3985.     if ((n=getbits(CBIT))==0)
  3986.     {
  3987.         register ulong *daddy=(ulong *) dad,k;
  3988.  
  3989.         for (i=(NC>>1),k=0;--i>=0;*((int *) clen)++=(int) k);
  3990.         k=getbits(CBIT);
  3991.         k=(k<<16)|k;
  3992.         for (i=2048;--i>=0;*daddy++=k);
  3993.     }
  3994.     else
  3995.     {
  3996.         register ushort *pttable=pt_table;
  3997.         register uint mask,bibu;
  3998.         register int c;
  3999.  
  4000.         i=0;
  4001.         while (i<n)
  4002.         {
  4003.             bibu=bitbuf;
  4004.             c=pttable[bibu>>8];
  4005.             if (c>=NT)
  4006.             {
  4007.                 mask=1U<<7;
  4008.                 do
  4009.                 {
  4010.                     if (bibu&mask)
  4011.                         c=right[c];
  4012.                     else
  4013.                         c=left[c];
  4014.                     mask>>=1;
  4015.                 } while (c>=NT);
  4016.             }
  4017.  
  4018.             fillbuf(pt_len[c]);
  4019.             if (c>2)
  4020.             {
  4021.                 *clen++=(c-2);
  4022.                 i++;
  4023.             }
  4024.             else if (c)
  4025.             {
  4026.                 if (--c==0)
  4027.                     c=getbits(4)+3;
  4028.                 else
  4029.                     c=getbits(CBIT)+20;
  4030.                 i+=c;
  4031.                 mask=0;
  4032.                 while (--c>=0)
  4033.                     *clen++=mask;
  4034.             }
  4035.             else
  4036.             {
  4037.                 *clen++=c;
  4038.                 i++;
  4039.             }
  4040.         }
  4041.  
  4042.         mask=0;
  4043.         bibu=NC;
  4044.         while (i<bibu)
  4045.         {
  4046.             *clen++=mask;
  4047.             i++;
  4048.         }
  4049.  
  4050.         if (!make_table(NC,c_len,12,(ushort *) dad))
  4051.             return(FAULT);
  4052.     }
  4053.  
  4054.     return(SUCCS);
  4055. }
  4056.  
  4057. void make_len(int root)
  4058. {
  4059.     register int i,k;
  4060.     register uint cum=0;
  4061.     register ushort *lencnt=len_cnt,*spt=sortptr;
  4062.  
  4063.     for (i=17;--i>=0;)
  4064.         *lencnt++=cum;
  4065.  
  4066.     count_len(root);
  4067.     for (i=17,k=0,lencnt=&len_cnt[17];--i>=0;)
  4068.         cum+=(*--lencnt)<<(k++);
  4069.  
  4070.     while (cum!=(1U<<16))
  4071.     {
  4072.         len_cnt[16]--;
  4073.  
  4074.         for (i=17,lencnt=&len_cnt[17];--i>=0;)
  4075.             if (*--lencnt)
  4076.             {
  4077.                 lencnt[0]--;
  4078.                 lencnt[1]+=2;
  4079.                 break;
  4080.             }
  4081.         cum--;
  4082.     }
  4083.  
  4084.     for (i=17,lencnt=&len_cnt[17];--i>=0;)
  4085.     {
  4086.         k=*--lencnt;
  4087.         while (--k>=0)
  4088.             len[*spt++]=i;
  4089.     }
  4090.  
  4091.     sortptr=spt;
  4092. }
  4093.  
  4094. #ifdef __SHELL__
  4095. #define print_title(a)
  4096. #else
  4097. void print_title(uchar **argv)
  4098. {
  4099.     if (!flg_q)
  4100.     {
  4101.         #if BETA==0
  4102.         register uchar *env;
  4103.         #endif
  4104.  
  4105.         if (!ptitel)
  4106.         {
  4107.             puts(title);
  4108.             ptitel++;
  4109.         }
  4110.  
  4111.         #if BETA
  4112.         if (!pargs)
  4113.         #else
  4114.         if (!pargs && (env=getenv("LHARCPAR"))!=NULL && atoi(env))
  4115.         #endif
  4116.         {
  4117.             register int i;
  4118.  
  4119.             pargs++;
  4120.             #if GERMAN
  4121.             puts("Argumente:");
  4122.             #else
  4123.             puts("Arguments:");
  4124.             #endif
  4125.             for (i=1;i<args;i++)
  4126.                 printf("'%s'\n",argv[i]);
  4127.             new_line();
  4128.         }
  4129.     }
  4130. }
  4131. #endif
  4132.  
  4133. uchar *get_ext(void)
  4134. {
  4135.     if (case_sensitive(arcname)==_PC_CASECONV)
  4136.         return(".LZH");
  4137.     else
  4138.         return(".lzh");
  4139. }
  4140.  
  4141. uchar *device(uchar *name)
  4142. {
  4143.     if (name[3]==':')
  4144.         name[3]='\0';
  4145.  
  4146.     if (!stricmp(name,"PRN") || !stricmp(name,"PRT"))
  4147.         return("PRN:");
  4148.     else if (!stricmp(name,"AUX"))
  4149.         return("AUX:");
  4150.     else if (!stricmp(name,"CON"))
  4151.         return("CON:");
  4152.     else
  4153.     {
  4154.         Convert_Filename(name,NULL,-1);
  4155.         return(name);
  4156.     }
  4157. }
  4158.  
  4159. int dev_arc(void)
  4160. {
  4161.     register uchar buf[MAXPATH],*path;
  4162.  
  4163.     if (__mint)
  4164.     {
  4165.         if (get_fname(arcname)==arcname)
  4166.             path=act_dir;
  4167.         else
  4168.             path=arcname;
  4169.  
  4170.         if (path[0]=='\0' || path[1]!=':')
  4171.         {
  4172.             buf[0]=Dgetdrv()+'a';
  4173.             buf[1]=':';
  4174.             if (path[0]!='\\')
  4175.             {
  4176.                 buf[2]='\\';
  4177.                 strcpy(buf+3,path);
  4178.             }
  4179.             else
  4180.                 strcpy(buf+2,path);
  4181.         }
  4182.         else
  4183.             strcpy(buf,path);
  4184.  
  4185.         strupr(buf);
  4186.  
  4187.         if (buf[0]=='U')
  4188.         {
  4189.             if (!strncmp(buf+3,"DEV\\",4))
  4190.                 return(1);
  4191.             else if (!strncmp(buf+3,"SHM\\",4) || !strncmp(buf+3,"PROC\\",5) || !strncmp(buf+3,"PIPE\\",5))
  4192.                 return(-1);
  4193.         }
  4194.     }
  4195.  
  4196.     return(0);
  4197. }
  4198.  
  4199. #ifndef __SHELL__
  4200. void ioredirect(int argc,uchar **argv)
  4201. {
  4202.     register uchar *p,c;
  4203.     register int i;
  4204.  
  4205.     for (i=0;i<argc;i++)
  4206.     {
  4207.         p=*argv++;
  4208.  
  4209.         if ((c=*p++)=='>' && o_handle<0)
  4210.         {
  4211.             if (!args)
  4212.                 args=i;
  4213.  
  4214.             if (*p=='>')
  4215.             {
  4216.                 if ((o_handle=Fopen(o_dir=device(++p),1))>=0)
  4217.                 {
  4218.                     o_dev=Fdup(1);
  4219.                     Fseek(0l,(int) o_handle,SEEK_END);
  4220.                     Fforce(1,(int) o_handle);
  4221.                     continue;
  4222.                 }
  4223.             }
  4224.  
  4225.             if ((o_handle=Fcreate(o_dir=device(p),0))>=0)
  4226.             {
  4227.                 o_dev=Fdup(1);
  4228.                 Fforce(1,(int) o_handle);
  4229.             }
  4230.         }
  4231.         else if (c=='<' && i_handle<0)
  4232.         {
  4233.             if (!args)
  4234.                 args=i;
  4235.  
  4236.             if ((i_handle=Fopen(p,0))>=0)
  4237.             {
  4238.                 i_dev=Fdup(0);
  4239.                 Fforce(0,(int) i_handle);
  4240.                 flg_m=1;
  4241.             }
  4242.         }
  4243.     }
  4244. }
  4245. #endif
  4246.  
  4247. #ifndef __SHELL__
  4248. void main(int argc,uchar **argv)
  4249. {
  4250.     register uchar *p,*q,*env,*env9,**old_argv=argv;
  4251.  
  4252.     ioredirect(argc,argv);
  4253.     if (args)
  4254.         argc=args;
  4255.     else
  4256.         args=argc;
  4257. #else
  4258. void argvmain(int argc,uchar **argv)
  4259. {
  4260.     register uchar *p,*q,*env,*env9;
  4261.  
  4262.     args=argc;
  4263. #endif
  4264.  
  4265.     if ((env=getenv("COLUMNS"))!=NULL)
  4266.     {
  4267.         maxblk=atoi(env) - 16;
  4268.         if (maxblk<24)
  4269.             maxblk=24;
  4270.     }
  4271.  
  4272.     argc--;
  4273. #ifndef __SHELL__
  4274.     if (argc<=0)
  4275.     {
  4276.         flg_h=1;
  4277.         puts(title_x);
  4278.         puts(use_1);
  4279.         wait_for_key(0);
  4280.         putchar('\r');
  4281.         puts(use_2);
  4282.         wait_for_key(0);
  4283.         putchar('\r');
  4284.         puts(use_3);
  4285.     }
  4286.     else
  4287. #endif
  4288.     {
  4289.         _lseed=clock();
  4290.         mkcrc();
  4291. #if __030
  4292.         get_cpu();
  4293. #endif
  4294.  
  4295.         Fsetdta(&_dta);
  4296.         getcwd(act_dir,MAXPATH);
  4297.         unix2dos(act_dir,0);
  4298.         slash(act_dir,1);
  4299.         Convert_Filename(act_dir,NULL,-1);
  4300.  
  4301.         fileptr=fileregbuf;
  4302.         *fileptr++='*';
  4303.         *fileptr++='\0';
  4304.  
  4305.         {
  4306.             register uint vers=Sversion();
  4307.             vers=(vers<<8) | (vers>>8);
  4308.  
  4309.             if (__mint)
  4310.                 oldtos=0;
  4311.             else
  4312.                 oldtos=(vers<0x0014);
  4313.         }
  4314.  
  4315.         buffer_gen=(uchar *) (((long) (buffer+128)) & (~15l));
  4316.  
  4317.         argv++;
  4318.         argc--;
  4319.         cmd=toupper(*(p=*argv++));
  4320.  
  4321.     #ifndef __SHELL__
  4322.         if (p[1]!='\0' || strchr("EXTDLVAUMFPRSC",cmd)==NULL || !argc)
  4323.         {
  4324.             register uchar dir[MAXPATH];
  4325.             register int compr;
  4326.  
  4327.             Convert_Filename(p,NULL,-1);
  4328.             if ((q=strstr(p,"*.*"))>NULL)
  4329.             {
  4330.                 if (q==p)
  4331.                     p=strcpy(dir,act_dir);
  4332.                 else
  4333.                     *q='\0';
  4334.             }
  4335.             slash(p,0);
  4336.  
  4337.             if (Attrib(p)>0)
  4338.                 compr=1;
  4339.             else
  4340.             {
  4341.                 switch (test_afx(p))
  4342.                 {
  4343.                 case 3:
  4344.                     {
  4345.                         register uchar *b=buffer_gen;
  4346.                         
  4347.                         q=b+1536;
  4348.                         compr=1;
  4349.  
  4350.                         while (b<q)
  4351.                         {
  4352.                             if (!strncmp(b,"SFX",3))
  4353.                                 goto _extract;
  4354.                             else if (*b++=='-' && b[3]=='-' && (*b=='a' || *b=='A' || *b=='l' || *b=='L'))
  4355.                                 break;
  4356.                         }
  4357.                     }
  4358.                     break;
  4359.                 case 2:
  4360.                     _extract:
  4361.                     compr=0;
  4362.                     break;
  4363.                 default:
  4364.                     compr=1;
  4365.                 }
  4366.             }
  4367.  
  4368.             if (strpbrk(get_fname(p),"*?")==NULL && compr)
  4369.             {
  4370.                 cmd='U';
  4371.                 pack++;
  4372.  
  4373.                 strcpy(arcname,p);
  4374.                 p=get_fname(p);
  4375.                 if ((q=strrchr(p,'.'))!=NULL)
  4376.                     *q='\0';
  4377.  
  4378.                 strcpy(stpcpy(backpath(arcname),p),get_ext());
  4379.  
  4380.                 if (q)
  4381.                     *q='.';
  4382.             }
  4383.             else
  4384.             {
  4385.                 cmd='X';
  4386.                 flg_g++;
  4387.                 backpath(strcpy(basedir,p));
  4388.                 pack+=2;
  4389.             }
  4390.  
  4391.             flg_x=3;
  4392.             flg_m++;
  4393.             argc++;
  4394.             argv--;
  4395.         }
  4396.     #endif
  4397.  
  4398.         cmdupdate=strchr("AUMFRD",cmd)!=NULL;
  4399.         cmdlist=strchr("AUMC",cmd)!=NULL;
  4400.  
  4401.         if ((env=getenv("TMP"))!=NULL || (env=getenv("TMPDIR"))!=NULL)
  4402.         {
  4403.             flg_w++;
  4404.             strcpy(workdir,env);
  4405.         }
  4406.  
  4407.         if ((env=getenv("UNPACKED"))!=NULL)
  4408.         {
  4409.             flg_U++;
  4410.             unpack=env;
  4411.         }
  4412.  
  4413.         if ((env=getenv("LHARC"))!=NULL)
  4414.         {
  4415.             for (p=env;*p;p++)
  4416.                 if (*p==' ' || *p=='\x08')
  4417.                     *p=0;
  4418.             env9=p;
  4419.             p=env;
  4420.             while (p<env9)
  4421.             {
  4422.                 while (!*p)
  4423.                     p++;
  4424.                 if (*p=='-' || *p=='/')
  4425.                     p++;
  4426.                 getsw(p);
  4427.                 while (*p)
  4428.                     p++;
  4429.             }
  4430.         }
  4431.  
  4432.         if (cmd=='C' || arcname[0])
  4433.             patno=0;
  4434.         else
  4435.             patno=-1;
  4436.  
  4437.         while (argc--)
  4438.         {
  4439.             p=*argv++;
  4440.             if (*p=='-')
  4441.             {
  4442.                 getsw(++p);
  4443.                 continue;
  4444.             }
  4445.             else if (*p=='/' && patno<0 && tstsw(p+1))
  4446.             {
  4447.                 if (cmdupdate && (wildcard(get_fname(p+1)) || multi_wild(p+1)))
  4448.                 {
  4449.                     getsw(++p);
  4450.                     continue;
  4451.                 }
  4452.                 else if ((q=strrchr(get_fname(p),'.'))!=NULL)
  4453.                 {
  4454.                     if (arc_ext(q)==FAULT)
  4455.                     {
  4456.                         getsw(++p);
  4457.                         continue;
  4458.                     }
  4459.                 }
  4460.                 else
  4461.                 {
  4462.                     getsw(++p);
  4463.                     continue;
  4464.                 }
  4465.             }
  4466.  
  4467.             print_title(old_argv);
  4468.             Convert_Filename(p,NULL,-1);
  4469.  
  4470.             if (patno<0)
  4471.             {
  4472.                 p=get_fname(strcpy(arcname,p));
  4473.  
  4474.                 if (*p=='\0' || (Device=dev_arc())<0)
  4475.                     error(NOARCNMERR,NULL,SUCCS);
  4476.  
  4477.                 multi_arc=multi_wild(p);
  4478.                 wild_arc=wildcard(p)|multi_arc;
  4479.  
  4480.                 if (cmdupdate && (strpbrk(p,"*?") || multi_arc))
  4481.                     error(NOARCNMERR,arcname,SUCCS);
  4482.  
  4483.                 if (!multi_arc && !Device)
  4484.                 {
  4485.                     if ((q=strrchr(p,'.'))==NULL)
  4486.                         strcat(arcname,get_ext());
  4487.                     else if (q[1]=='\0')
  4488.                         strcpy(q,get_ext());
  4489.                     else if (flg_m!=1 && cmdupdate && arc_ext(q)==FAULT)
  4490.                     {
  4491.                         printf(M_NOTLZH,get_fname(arcname));
  4492.                         if (get_key("YN")=='N')
  4493.                         {
  4494.                             errorlevel|=128;
  4495.                             lha_exit();
  4496.                         }
  4497.                     }
  4498.                 }
  4499.                 patno++;
  4500.             }
  4501.             else if (pack<2)
  4502.             {
  4503.                 if (pack)
  4504.                 {
  4505.                     slash(p,0);
  4506.  
  4507.                     if (strstr(p,"*.*")!=NULL)
  4508.                         flg_r++;
  4509.                     else if (Attrib(p)>0)
  4510.                     {
  4511.                         register uchar path[MAXPATH];
  4512.  
  4513.                         flg_r++;
  4514.                         slash(strcpy(path,p),1);
  4515.                         if ((p=strdup(path))==NULL)
  4516.                             error(MEMOVRERR,NULL,SUCCS);
  4517.                     }
  4518.                 }
  4519.  
  4520.                 newfile(p);
  4521.             }
  4522.         }
  4523.  
  4524.         if (args>2 && pack==1)
  4525.             pack=0;
  4526.         else if (pack==2)
  4527.             pack=0;
  4528.  
  4529.         print_title(old_argv);
  4530.  
  4531.         if (patno<0)
  4532.             error(NOARCNMERR,NULL,SUCCS);
  4533.         else if (!patno && cmd!='D')
  4534.         {
  4535.             travel_path[0]="";
  4536.             travel_len[0]=travel_file[0]=travel_rel[0]=0;
  4537.             travel_wild[0]=all=SUCCS;
  4538.             patno++;
  4539.             flg_p=0;
  4540.         }
  4541.  
  4542.         fn_name=path_conf(basedir,_PC_NAME_MAX);
  4543.         pt_name=path_conf(basedir,_PC_PATH_MAX);
  4544.         if (pt_name>MAXPATH)
  4545.             pt_name=MAXPATH;
  4546.         Case=case_sensitive(basedir);
  4547.  
  4548.         if (flg_U)
  4549.             Convert_Filename(unpack,NULL,0);
  4550.  
  4551.         Convert_Filename(workdir,NULL,0);
  4552.         slash(workdir,1);
  4553.         tstdir(workdir,-1);
  4554.  
  4555.         Convert_Filename(incldir,NULL,0);
  4556.         slash(incldir,1);
  4557.  
  4558.         if (Device)
  4559.         {
  4560.             if (strchr("AMEXTPLV",cmd)==NULL)
  4561.                 error(NOARCERR,arcname,SUCCS);
  4562.             else if (strchr("EXTP",cmd))
  4563.                 flg_d=0;
  4564.             flg_w=0;
  4565.         }
  4566.  
  4567.         MakeBuffers();
  4568.  
  4569.         if (cmdupdate || cmd=='C')
  4570.             executecmd();
  4571.         else
  4572.         {
  4573.             register uchar *f,*p,*q,arc[MAXPATH];
  4574.             register long handle,buf[MAXPATH>>2];
  4575.             register int done,cnt=0,len,case_s;
  4576.  
  4577.             if (__mint)
  4578.                 _gemdos=(path_conf(arcname,_PC_NAME_MAX)<=12 && case_sensitive(arcname)==_PC_CASECONV) ? 1 : 0;
  4579.             else
  4580.                 _gemdos=1;
  4581.  
  4582.             if (!_gemdos)
  4583.             {
  4584.                 backpath(strcpy(arc,arcname));
  4585.  
  4586.                 if (arc[0]!='\0')
  4587.                     handle=Dopendir(arc,0);
  4588.                 else
  4589.                     handle=Dopendir(act_dir,0);
  4590.  
  4591.                 if ((handle&0xff000000l)==0xff000000l)
  4592.                     error(NOARCERR,arcname,SUCCS);
  4593.                 else
  4594.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  4595.                 f=(uchar *) &buf[1];
  4596.             }
  4597.             else
  4598.             {
  4599.                 strcpy(arc,arcname);
  4600.                 if (wild_arc)
  4601.                     strcpy(backpath(arc),"*.*");
  4602.                 done=Fsfirst(arc,0x07);
  4603.                 f=_dta.dta_name;
  4604.             }
  4605.  
  4606.             case_s=(flg_S==2 || (!flg_S && case_sensitive(arcname)!=_PC_CASESENS));
  4607.             q=get_fname(arcname);
  4608.             p=backpath(arc);
  4609.  
  4610.             while(!done)
  4611.             {
  4612.                 if (case_s)
  4613.                     strupr(f);
  4614.  
  4615.                 if ((_gemdos && wild_arc==FAULT) || chk_wild(f,q,flg_W))
  4616.                 {
  4617.                     strcpy(p,f);
  4618.                     if (o_dir!=NULL && !strcmp(p,o_dir))
  4619.                         goto arc_next;
  4620.  
  4621.                     if (!_gemdos)
  4622.                     {
  4623.                         if (*f!='.' || (strcmp(f,".") && strcmp(f,"..")))
  4624.                         {
  4625.                             Fxattr(0,arc,(uchar *) &xattr);
  4626.                             if (xattr.attr & (FA_LABEL|FA_DIR))
  4627.                                 goto arc_next;
  4628.                             *p='\0';
  4629.                         }
  4630.                         else
  4631.                             goto arc_next;
  4632.                     }
  4633.  
  4634.                     if (cnt<MAX_ARC)
  4635.                     {
  4636.                         len=(int) strlen(f)+1;
  4637.                         if ((fileptr-fileregbuf+len)>=(FILEBUFSIZ-1))
  4638.                             message(M_FILETAB,f);
  4639.                         else
  4640.                         {
  4641.                             strcpy(fileptr,f);
  4642.                             arc_file[cnt++]=(int) (fileptr-fileregbuf);
  4643.                             fileptr+=len;
  4644.                         }
  4645.                     }
  4646.                     else
  4647.                         message(M_FILETAB,f);
  4648.                 }
  4649.  
  4650.                 arc_next:
  4651.                 if (_gemdos)
  4652.                     done=Fsnext();
  4653.                 else
  4654.                     done=(int) Dreaddir(MAXPATH,handle,(uchar *) buf);
  4655.             }
  4656.  
  4657.             if (!_gemdos)
  4658.                 Dclosedir(handle);
  4659.  
  4660.             if (!cnt)
  4661.                 error(NOARCERR,arcname,SUCCS);
  4662.             else
  4663.             {
  4664.                 if (!flg_q)
  4665.                 #if GERMAN
  4666.                     printf(" Archive gefunden : %d\n",cnt);
  4667.                 #else
  4668.                     printf(" Archives matched : %d\n",cnt);
  4669.                 #endif
  4670.  
  4671.                 q=basedir+strlen(basedir);
  4672.  
  4673.                 while(--cnt>=0)
  4674.                 {
  4675.                     f=&fileregbuf[arc_file[cnt]];
  4676.                     strcpy(backpath(arcname),f);
  4677.                     if (cmd=='X' || cmd=='E')
  4678.                     {
  4679.                         if (flg_g && (p=strrchr(f,'.'))!=NULL)
  4680.                         {
  4681.                             *p='\0';
  4682.                             strcpy(stpcpy(q,f),"\\");
  4683.                         }
  4684.  
  4685.                         tstdir(basedir,-1);
  4686.                     }
  4687.  
  4688.                     executecmd();
  4689.                 }
  4690.             }
  4691.  
  4692.             if (cmd!='L' && cmd!='V')
  4693.                 tstpat();
  4694.         }
  4695.     }
  4696.  
  4697.     lha_exit();
  4698. }
  4699.